package com.amazon.ads.apidemo.fragments;

import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ScrollView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.amazon.ads.apidemo.HttpStatusCode;
import com.amazon.ads.apidemo.R;
import com.amazon.ads.apidemo.utils.L;
import com.amazon.ads.ema.api.model.DeviceData;
import com.amazon.ads.ema.api.model.DeviceInfo;
import com.amazon.ads.ema.api.model.ResourceData;
import com.amazon.ads.ema.api.model.SystemResources;

/**
 * Fragment for device information and screenshot functionality
 */
public class DeviceInfoFragment extends BaseFragment {
    private TextView mTvDeviceInfo;
    private TextView mTvSystemInfo;
    private ScrollView mScrollView;
    private Button mBtnGetDeviceInfo;
    private Button mBtnGetSystemInfo;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_device_info, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        initializeBase();

        // Initialize views
        mScrollView = view.findViewById(R.id.scroll_view_device_info);
        mBtnGetDeviceInfo = view.findViewById(R.id.btn_get_device_info);
        mBtnGetSystemInfo = view.findViewById(R.id.btn_get_system_info);
        mTvDeviceInfo = view.findViewById(R.id.tv_device_info);
        mTvSystemInfo = view.findViewById(R.id.tv_system_info);

        // Set click listeners
        mBtnGetDeviceInfo.setOnClickListener(v -> getDeviceInfo());
        mBtnGetSystemInfo.setOnClickListener(v -> getSystemInfo());

        // Setup keyboard shortcuts
        setupKeyboardShortcuts(view);
    }

    @Override
    public void onResume() {
        super.onResume();
        L.i("DeviceInfoFragment onResume - requesting focus on ScrollView");
        // Request focus on ScrollView when fragment becomes visible
        if (mScrollView != null) {
            boolean focusResult = mScrollView.requestFocus();
            L.i("DeviceInfoFragment focus request result: " + focusResult + ", hasFocus: " + mScrollView.hasFocus());
        } else {
            L.w("DeviceInfoFragment onResume - mScrollView is null!");
        }
    }

    private void setupKeyboardShortcuts(View view) {
        L.i("DeviceInfoFragment setupKeyboardShortcuts");
        // Set listener on ScrollView instead of fragment root view
        if (mScrollView != null) {
            mScrollView.setFocusable(true);
            mScrollView.setFocusableInTouchMode(true);
            mScrollView.requestFocus();
            mScrollView.setOnKeyListener((v, keyCode, event) -> {
                L.d("DeviceInfoFragment OnKeyListener (ScrollView) - keyCode: " + keyCode + ", action: " + event.getAction() + ", KeyEvent: " +
                        KeyEvent.keyCodeToString(keyCode));

                if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    switch (keyCode) {
                    case KeyEvent.KEYCODE_DPAD_UP:
                        L.i("DeviceInfoFragment handling UP arrow");
                        if (mScrollView != null) {
                            mScrollView.smoothScrollBy(0, -200);
                            return true;
                        }
                        break;
                    case KeyEvent.KEYCODE_DPAD_DOWN:
                        L.i("DeviceInfoFragment handling DOWN arrow");
                        if (mScrollView != null) {
                            mScrollView.smoothScrollBy(0, 200);
                            return true;
                        }
                        break;
                    }
                }
                L.d("DeviceInfoFragment OnKeyListener - returning false (not handled)");
                return false;
            });
            L.i("DeviceInfoFragment keyboard shortcuts setup complete - listener on ScrollView");
        } else {
            L.w("DeviceInfoFragment setupKeyboardShortcuts - mScrollView is null!");
        }
    }

    /**
     * Public method to trigger getting device info from MainActivity
     */
    public void triggerGetDeviceInfo() {
        L.i("DeviceInfoFragment triggerGetDeviceInfo() called from MainActivity");
        showButtonPressEffect(mBtnGetDeviceInfo);
        getDeviceInfo();
    }

    /**
     * Public method to trigger getting system info from MainActivity
     */
    public void triggerGetSystemInfo() {
        L.i("DeviceInfoFragment triggerGetSystemInfo() called from MainActivity");
        showButtonPressEffect(mBtnGetSystemInfo);
        getSystemInfo();
    }

    private void getDeviceInfo() {
        if (!checkConnection())
            return;

        updateLastApiCall("Getting device info...");

        new Thread(() -> {
            DeviceInfo response = mApiClient.getDeviceInfo();
            mHandler.post(() -> {
                if (response.code == HttpStatusCode.OK_200) {
                    String info = formatDeviceInfo(response.data);
                    mTvDeviceInfo.setText(info);
                    mTvDeviceInfo.setVisibility(View.VISIBLE);
                    updateLastApiCall("Device info retrieved");
                } else {
                    showError("Failed", response.message);
                }
            });
        }).start();
    }

    private void getSystemInfo() {
        if (!checkConnection())
            return;

        updateLastApiCall("Getting system info...");

        new Thread(() -> {
            SystemResources response = mApiClient.getSystemResources();
            mHandler.post(() -> {
                if (response.code == HttpStatusCode.OK_200) {
                    String info = formatSystemResources(response.data);
                    mTvSystemInfo.setText(info);
                    mTvSystemInfo.setVisibility(View.VISIBLE);
                    updateLastApiCall("System resources retrieved");
                } else {
                    showError("Failed", response.message);
                }
            });
        }).start();
    }


    private String formatDeviceInfo(DeviceData data) {
        if (data == null)
            return "No data available";

        String sb = "Device Serial Number: " + (data.dsn != null ? data.dsn : "N/A") + "\n\n" +
                "Model: " + (data.model != null ? data.model : "N/A") + "\n\n" +
                "Kiosk App: " + (data.kioskApp != null ? data.kioskApp : "N/A") + "\n\n" +
                "Timezone: " + (data.timezone != null ? data.timezone : "N/A") + "\n\n" +
                "Monitor Info: " + (data.monitorInfo != null ? data.monitorInfo : "N/A") + "\n\n" +
                "Uptime: " + formatUptime(data.elapsedMs);

        return sb;
    }

    private String formatSystemResources(ResourceData data) {
        if (data == null)
            return "No data available";

        StringBuilder sb = new StringBuilder();

        // Memory Info
        if (data.memory != null) {
            sb.append("Memory:\n");
            sb.append("  Total: ").append(formatBytes(data.memory.total)).append("\n");
            sb.append("  Used: ").append(formatBytes(data.memory.used)).append(" (").append(String.format("%.1f%%", data.memory.ratio)).append(")\n");
            sb.append("  Free: ").append(formatBytes(data.memory.free)).append("\n\n");
        }

        // Storage Info
        if (data.storage != null) {
            sb.append("Storage:\n");
            sb.append("  Total: ").append(formatBytes(data.storage.total)).append("\n");
            sb.append("  Used: ").append(formatBytes(data.storage.used)).append(" (").append(String.format("%.1f%%", data.storage.ratio))
                    .append(")\n");
            sb.append("  Free: ").append(formatBytes(data.storage.free)).append("\n\n");
        }

        // CPU Info
        if (data.cpu != null) {
            sb.append("CPU Usage: ").append(String.format("%.1f%%", data.cpu.usagePercent)).append("\n\n");
        }

        // Temperature Info
        if (data.temperature != null) {
            sb.append("Temperature:\n");
            sb.append("  CPU: ").append(String.format("%.1f°C", data.temperature.cpuCelsius)).append("\n");
            sb.append("  GPU: ").append(String.format("%.1f°C", data.temperature.gpuCelsius)).append("\n");
            sb.append("  State: ").append(data.temperature.thermalState).append("\n\n");
        }

        sb.append("Uptime: ").append(formatUptime(data.elapsedMs));

        return sb.toString();
    }

    private String formatBytes(long bytes) {
        if (bytes < 1024)
            return bytes + " B";
        int exp = (int) (Math.log(bytes) / Math.log(1024));
        String pre = "KMGTPE".charAt(exp - 1) + "";
        return String.format("%.1f %sB", bytes / Math.pow(1024, exp), pre);
    }

    private String formatUptime(long elapsedMs) {
        long seconds = elapsedMs / 1000;
        long minutes = seconds / 60;
        long hours = minutes / 60;
        long days = hours / 24;

        if (days > 0) {
            return String.format("%dd %dh %dm", days, hours % 24, minutes % 60);
        } else if (hours > 0) {
            return String.format("%dh %dm %ds", hours, minutes % 60, seconds % 60);
        } else {
            return String.format("%dm %ds", minutes, seconds % 60);
        }
    }
}
