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.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.Spinner;
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.ApiResponse;
import com.amazon.ads.ema.api.model.NetworkData;
import com.amazon.ads.ema.api.model.NetworkStatus;
import com.amazon.ads.ema.api.model.WifiConfig;

/**
 * Fragment for network status and WiFi configuration
 */
public class NetworkFragment extends BaseFragment {
    // Security types
    private static final String[] SECURITY_TYPES = {"OPEN", "WEP", "WPA", "WPA2_PSK", "WPA3"};
    private TextView mTvNetworkStatus;
    private ScrollView mScrollView;
    private Button mBtnGetNetworkStatus;
    // WiFi Configuration views
    private EditText mEtWifiSsid;
    private Spinner mSpinnerSecurityType;
    private EditText mEtWifiPassword;
    private CheckBox mCbHiddenNetwork;
    private EditText mEtPriority;
    private Button mBtnConfigureWifi;
    private TextView mTvWifiConfigResult;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_network, 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_network);
        mBtnGetNetworkStatus = view.findViewById(R.id.btn_get_network_status);
        mTvNetworkStatus = view.findViewById(R.id.tv_network_status);

        // Initialize WiFi configuration views
        mEtWifiSsid = view.findViewById(R.id.et_wifi_ssid);
        mSpinnerSecurityType = view.findViewById(R.id.spinner_security_type);
        mEtWifiPassword = view.findViewById(R.id.et_wifi_password);
        mCbHiddenNetwork = view.findViewById(R.id.cb_hidden_network);
        mEtPriority = view.findViewById(R.id.et_priority);
        mBtnConfigureWifi = view.findViewById(R.id.btn_configure_wifi);
        mTvWifiConfigResult = view.findViewById(R.id.tv_wifi_config_result);

        // Setup security type spinner
        ArrayAdapter<String> adapter = new ArrayAdapter<>(requireContext(), android.R.layout.simple_spinner_item, SECURITY_TYPES);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        mSpinnerSecurityType.setAdapter(adapter);
        mSpinnerSecurityType.setSelection(3); // Default to WPA2_PSK

        // Set click listeners
        mBtnGetNetworkStatus.setOnClickListener(v -> getNetworkStatus());
        mBtnConfigureWifi.setOnClickListener(v -> configureWifi());

        // Setup keyboard shortcuts
        setupKeyboardShortcuts(view);
    }

    @Override
    public void onResume() {
        super.onResume();
        if (getView() != null) {
            getView().requestFocus();
        }
    }

    private void setupKeyboardShortcuts(View view) {
        view.setFocusable(true);
        view.setFocusableInTouchMode(true);
        view.setOnKeyListener((v, keyCode, event) -> {
            if (event.getAction() == KeyEvent.ACTION_DOWN) {
                switch (keyCode) {
                case KeyEvent.KEYCODE_DPAD_UP:
                    // Scroll up
                    if (mScrollView != null) {
                        mScrollView.smoothScrollBy(0, -200);
                        return true;
                    }
                    break;
                case KeyEvent.KEYCODE_DPAD_DOWN:
                    // Scroll down
                    if (mScrollView != null) {
                        mScrollView.smoothScrollBy(0, 200);
                        return true;
                    }
                    break;
                }
            }
            return false;
        });
    }

    /**
     * Public method to trigger action from MainActivity
     */
    public void triggerGetNetworkStatus() {
        L.i("NetworkFragment triggerGetNetworkStatus() called from MainActivity");
        showButtonPressEffect(mBtnGetNetworkStatus);
        getNetworkStatus();
    }

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

        updateLastApiCall("Getting network status...");

        new Thread(() -> {
            NetworkStatus response = mApiClient.getNetworkStatus();
            mHandler.post(() -> {
                if (response.code == HttpStatusCode.OK_200 && response.data != null) {
                    String status = formatNetworkStatus(response.data);
                    mTvNetworkStatus.setText(status);
                    mTvNetworkStatus.setVisibility(View.VISIBLE);
                    updateLastApiCall("Network status retrieved");
                } else {
                    showError("Failed to get network status", response.message);
                }
            });
        }).start();
    }

    private String formatNetworkStatus(NetworkData data) {
        if (data == null)
            return "No network data available";

        StringBuilder sb = new StringBuilder();

        // WiFi Info
        if (data.wifi != null) {
            sb.append("WiFi Status:\n");
            sb.append("  Connected: ").append(data.wifi.connected).append("\n");
            if (data.wifi.connected) {
                sb.append("  SSID: ").append(data.wifi.ssid).append("\n");
                sb.append("  Signal: ").append(data.wifi.signalStrengthDbm).append(" dBm").append(" (Level ").append(data.wifi.signalLevel)
                        .append("/4)\n");
                sb.append("  Speed: ").append(data.wifi.linkSpeedMbps).append(" Mbps\n");
                sb.append("  IP: ").append(data.wifi.ipAddress).append("\n");
                sb.append("  MAC: ").append(data.wifi.macAddress).append("\n");
            }
            sb.append("\n");
        }

        // Ethernet Info
        if (data.ethernet != null) {
            sb.append("Ethernet Status:\n");
            sb.append("  Connected: ").append(data.ethernet.connected).append("\n");
            if (data.ethernet.connected) {
                sb.append("  IP: ").append(data.ethernet.ipAddress).append("\n");
                sb.append("  MAC: ").append(data.ethernet.macAddress).append("\n");
            }
        }

        return sb.toString();
    }

    /**
     * Public method to trigger WiFi configuration from MainActivity
     */
    public void triggerConfigureWifi() {
        L.i("NetworkFragment triggerConfigureWifi() called from MainActivity");
        showButtonPressEffect(mBtnConfigureWifi);
        configureWifi();
    }

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

        // Get input values
        String ssid = mEtWifiSsid.getText().toString().trim();
        String password = mEtWifiPassword.getText().toString().trim();
        String securityType = SECURITY_TYPES[mSpinnerSecurityType.getSelectedItemPosition()];
        boolean hidden = mCbHiddenNetwork.isChecked();
        String priorityStr = mEtPriority.getText().toString().trim();

        // Validate SSID
        if (ssid.isEmpty()) {
            showError("Invalid Input", "Please enter a WiFi network name (SSID)");
            return;
        }

        // Validate password for secured networks
        if (!securityType.equals("OPEN") && password.isEmpty()) {
            showError("Invalid Input", "Please enter a password for secured network");
            return;
        }

        // WPA/WPA2/WPA3 PSK/SAE passphrases must be 8-63 characters. Catch the
        // common too-short input here instead of letting it fail downstream.
        if ((securityType.equals("WPA") || securityType.equals("WPA2_PSK") || securityType.equals("WPA3"))
                && password.length() < 8) {
            showError("Invalid Input", "Password must be at least 8 characters for " + securityType);
            return;
        }

        // Parse priority
        int priority = 0;
        try {
            if (!priorityStr.isEmpty()) {
                priority = Integer.parseInt(priorityStr);
            }
        } catch (NumberFormatException e) {
            showError("Invalid Input", "Priority must be a valid number");
            return;
        }

        updateLastApiCall("Configuring WiFi network: " + ssid);

        // Create WiFi configuration
        WifiConfig config = new WifiConfig();
        config.ssid = ssid;
        config.password = password;
        config.securityType = securityType;
        config.hidden = hidden;
        config.priority = priority;
        config.staticIp = null; // Using DHCP

        // Make variables final for use in lambda
        final String finalSsid = ssid;
        final String finalSecurityType = securityType;
        final boolean finalHidden = hidden;
        final int finalPriority = priority;

        new Thread(() -> {
            ApiResponse response = mApiClient.configureWifi(config);
            mHandler.post(() -> {
                if (response.code == HttpStatusCode.OK_200) {
                    String result = "WiFi configuration successful!\n\n" + "Network: " + finalSsid + "\n" + "Security: " + finalSecurityType + "\n" +
                            "Hidden: " + finalHidden + "\n" + "Priority: " + finalPriority;
                    mTvWifiConfigResult.setText(result);
                    mTvWifiConfigResult.setVisibility(View.VISIBLE);
                    updateLastApiCall("WiFi configured successfully");

                    // Clear input fields after successful configuration
                    mEtWifiSsid.setText("");
                    mEtWifiPassword.setText("");
                    mSpinnerSecurityType.setSelection(3); // Reset to WPA2_PSK
                    mCbHiddenNetwork.setChecked(false);
                    mEtPriority.setText("0");
                } else {
                    String errorMsg = "Failed to configure WiFi\n" + "Code: " + response.code + "\n" + "Message: " + response.message;
                    mTvWifiConfigResult.setText(errorMsg);
                    mTvWifiConfigResult.setVisibility(View.VISIBLE);
                    showError("WiFi Configuration Failed", response.message);
                }
            });
        }).start();
    }

}
