package com.dspread.pos.common.base;

import com.dspread.pos.ui.screensaver.ScreensaverActivity;
import android.app.Application;
import android.content.Context;

import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.databinding.Observable;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;

import com.dspread.pos.common.websocket.WebSocketManager;
import com.dspread.pos.common.websocket.WebSocketViewModel;
import com.dspread.pos.data.local.PreferencesManager;
import com.dspread.pos.utils.DevUtils;
import com.dspread.pos.utils.DeviceUtils;
import com.dspread.pos.utils.PosParameters;

import org.json.JSONException;
import org.json.JSONObject;

import me.goldze.mvvmhabit.base.BaseViewModel;
import me.goldze.mvvmhabit.utils.SPUtils;

public class BaseAppViewModel extends BaseViewModel implements WebSocketManager.WebSocketListener {
    private static final String TAG = "BaseAVM";

    // In BaseAppViewModel.java, add these members:
    private static final long SCREENSAVER_TIMEOUT = 30000; // 30 seconds
    private Handler screensaverHandler = new Handler(Looper.getMainLooper());
    private Runnable screensaverRunnable = this::startScreensaver;
    private MutableLiveData<Boolean> isScreensaverActive = new MutableLiveData<>(false);


    protected Application application;
    protected Context context;
    protected PreferencesManager prefs;
    private WebSocketManager webSocketManager;
    private MutableLiveData<Boolean> webSocketConnectionStatus = new MutableLiveData<>();
    private MutableLiveData<String> webSocketError = new MutableLiveData<>();
    private String deviceId = SPUtils.getInstance().getString("posID"); // Unique ID per device
    private String deviceModel = DeviceUtils.getDeviceName();

    public BaseAppViewModel(@NonNull Application application) {
        super(application);
        Log.d(TAG, "BaseAppViewModel: Started");

        this.application = application;
        this.context = application.getApplicationContext();
        this.prefs = PreferencesManager.getInstance(application);
        // Initialize WebSocketManager
        webSocketManager = new WebSocketManager(this);
        // Connect to WebSocket server
        connectWebSocket("ws://yuzpayqr.mulberrypos.com:4780");
    }

    /**
     * Connect to WebSocket server
     * @param serverUrl WebSocket server URL (e.g., "ws://your-server:8080")
     */
    public void connectWebSocket(String serverUrl) {
        webSocketManager.connect(serverUrl);
    }

    /**
     * Disconnect from WebSocket server
     */
    public void disconnectWebSocket() {
        webSocketManager.disconnect();
    }

    /**
     * Send message via WebSocket
     * @param message Message to send
     */
    public void sendWebSocketMessage(String message) {
        webSocketManager.sendMessage(message);
    }

    /**
     * Get WebSocket connection status LiveData
     */
    public LiveData<Boolean> getWebSocketConnectionStatus() {
        return webSocketConnectionStatus;
    }

    /**
     * Get WebSocket error LiveData
     */
    public LiveData<String> getWebSocketError() {
        return webSocketError;
    }

    // WebSocketListener callbacks
    @Override
    public void onMessageReceived(String message) {
        try {
            Log.d("BaseAVM", "onMessageReceived: " + message);
            JSONObject json = new JSONObject(message);
            if (json.has("deviceId") &&
                    !json.getString("deviceId").equals(deviceId)) {
                // Message not intended for this device
                return;
            }

            if (json.has("type")) {
                String type = json.getString("type");


                switch (type) {
                    case "configuration":
                        new Handler(Looper.getMainLooper()).post(() -> {
                            PosParameters.updateFromJson(json.toString(), context);
                            onConfigurationUpdated();
                        });

//                        PosParameters.updateFromJson(json.toString(), context);
//                        onConfigurationUpdated();
                        break;
                    case "payment":
                        onPaymentUpdated(json.toString());
                        break;
                    default:
                        Log.d("BaseAppViewModel", "Unknown message type: " + type);
                }
            }
        } catch (JSONException e) {
            Log.e("BaseAppViewModel", "Error parsing WebSocket message", e);
            webSocketError.postValue("Error parsing message: " + e.getMessage());
        }
    }

    @Override
    public void onConnectionEstablished() {
        webSocketConnectionStatus.postValue(true);
        Log.d("BaseAppViewModel", "WebSocket connected " + deviceId + deviceModel);
        // Send identification immediately after connection
        JSONObject identification = new JSONObject();
        try {
            identification.put("type", "identification");
            identification.put("deviceId", deviceId);
            identification.put("model", deviceModel);
            sendWebSocketMessage(identification.toString());
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onConnectionClosed() {
        webSocketConnectionStatus.postValue(false);
        Log.d("BaseAppViewModel", "WebSocket disconnected");
    }

    @Override
    public void onError(String error) {
        webSocketError.postValue(error);
        Log.e("BaseAppViewModel", "WebSocket error: " + error);
    }

    protected void onConfigurationUpdated() {
        Log.d("BaseAppViewModel", "onConfigurationUpdated: ");

        // Override in child classes for specific update handling
    }

    protected void onPaymentUpdated(String paymentData) {
        Log.d("BaseAppViewModel", "onPaymentUpdated: " + paymentData);
        // Override in child classes for specific update handling
    }


    // Add a public ViewModel method
    protected void showLoading() {
        showDialog();
    }

    protected void hideLoading() {
        dismissDialog();
    }


    // Add these methods:
    public void resetScreensaverTimer() {
        Log.d(TAG, "Resetting screensaver timer");
        screensaverHandler.removeCallbacks(screensaverRunnable);
        if (!Boolean.TRUE.equals(isScreensaverActive.getValue())) {
            screensaverHandler.postDelayed(screensaverRunnable, SCREENSAVER_TIMEOUT);
        }
    }

    public void cancelScreensaverTimer() {
        Log.d(TAG, "Cancelling screensaver timer");
        screensaverHandler.removeCallbacks(screensaverRunnable);
    }

    private void startScreensaver() {
        Log.d(TAG, "Starting screensaver");
        isScreensaverActive.postValue(true);
        Intent intent = new Intent(context, ScreensaverActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }

    public void stopScreensaver() {
        Log.d(TAG, "Stopping screensaver");
        isScreensaverActive.postValue(false);
        // The activity will finish itself when touched
    }

    public LiveData<Boolean> getIsScreensaverActive() {
        return isScreensaverActive;
    }

    @Override
    protected void onCleared() {
        super.onCleared();
        Log.d("BaseAVM", "ViewModel cleared");
        // Clean up WebSocket connection when ViewModel is cleared
//        webSocketManager.disconnect();
        cancelScreensaverTimer();
    }
}