package com.grigowashere.aismap.settings;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.google.android.material.switchmaterial.SwitchMaterial;
import com.grigowashere.aismap.R;
import com.grigowashere.aismap.utils.SettingsManager;

import java.util.ArrayList;
import java.util.List;

public class InterfacesSettingsActivity extends AppCompatActivity {

    private static final String TAG = "InterfacesSettings";
    private static final int REQ_PERMS_BLE = 2001;

    private SettingsManager settingsManager;

    // UDP
    private EditText etUdpPort;
    private SwitchMaterial swUdpEnabled;

    // BLE
    private SwitchMaterial swBleEnabled;
    private EditText etBleMac;

    // BLE UDP Bridge
    private SwitchMaterial swBleBridgeEnabled;
    private EditText etBleBridgeHost;
    private EditText etBleBridgePort;

    private Button btnSave;
    private Button btnCancel;

    // Scan UI
    private Button btnBleScan;
    private Button btnBleStopScan;
    private RecyclerView rvBle;
    private DevicesAdapter devicesAdapter;

    private BluetoothAdapter btAdapter;
    private BluetoothLeScanner bleScanner;
    private boolean scanning = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_interfaces_settings);
        settingsManager = new SettingsManager(this);
        BluetoothManager bm = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        btAdapter = bm != null ? bm.getAdapter() : null;
        bleScanner = btAdapter != null ? btAdapter.getBluetoothLeScanner() : null;
        initViews();
        loadValues();
        setupHandlers();
        setupRecycler();
    }

    private void initViews() {
        etUdpPort = findViewById(R.id.et_udp_port);
        swUdpEnabled = findViewById(R.id.switch_udp_enabled);
        swBleEnabled = findViewById(R.id.switch_ble_enabled);
        etBleMac = findViewById(R.id.et_ble_mac);
        swBleBridgeEnabled = findViewById(R.id.switch_ble_udp_bridge_enabled);
        etBleBridgeHost = findViewById(R.id.et_ble_udp_host);
        etBleBridgePort = findViewById(R.id.et_ble_udp_port);
        btnSave = findViewById(R.id.btn_save);
        btnCancel = findViewById(R.id.btn_cancel);
        btnBleScan = findViewById(R.id.btn_ble_scan);
        btnBleStopScan = findViewById(R.id.btn_ble_stop_scan);
        rvBle = findViewById(R.id.rv_ble_devices);
    }

    private void loadValues() {
        etUdpPort.setText(String.valueOf(settingsManager.getUDPPort()));
        swUdpEnabled.setChecked(settingsManager.isUDPEnabled());

        swBleEnabled.setChecked(settingsManager.isBLEEnabled());
        etBleMac.setText(settingsManager.getBLEDeviceMac());

        swBleBridgeEnabled.setChecked(settingsManager.isBleUdpBridgeEnabled());
        etBleBridgeHost.setText(settingsManager.getBleUdpBridgeHost());
        etBleBridgePort.setText(String.valueOf(settingsManager.getBleUdpBridgePort()));
    }

    private void setupHandlers() {
        btnCancel.setOnClickListener(v -> finish());
        btnSave.setOnClickListener(v -> saveAndExit());
        btnBleScan.setOnClickListener(v -> startScan());
        btnBleStopScan.setOnClickListener(v -> stopScan());
    }

    private void setupRecycler() {
        devicesAdapter = new DevicesAdapter(device -> {
            if (device == null) return;
            String mac = device.getAddress();
            etBleMac.setText(mac);
            Toast.makeText(this, "Выбрано устройство: " + device.getName() + " (" + mac + ")", Toast.LENGTH_SHORT).show();
        });
        rvBle.setLayoutManager(new LinearLayoutManager(this));
        rvBle.setAdapter(devicesAdapter);
    }

    private void startScan() {
        if (btAdapter == null || !btAdapter.isEnabled()) {
            Toast.makeText(this, "Bluetooth не включен", Toast.LENGTH_SHORT).show();
            return;
        }
        if (!ensureBlePerms()) return;
        if (bleScanner == null) {
            Toast.makeText(this, "BLE Scanner недоступен", Toast.LENGTH_SHORT).show();
            return;
        }
        if (scanning) return;
        devicesAdapter.clear();
        bleScanner.startScan(scanCallback);
        scanning = true;
        Toast.makeText(this, "BLE сканирование запущено", Toast.LENGTH_SHORT).show();
    }

    private void stopScan() {
        if (!scanning) return;
        try { bleScanner.stopScan(scanCallback); } catch (Exception ignore) {}
        scanning = false;
        Toast.makeText(this, "BLE сканирование остановлено", Toast.LENGTH_SHORT).show();
    }

    private boolean ensureBlePerms() {
        List<String> need = new ArrayList<>();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) need.add(Manifest.permission.BLUETOOTH_SCAN);
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) need.add(Manifest.permission.BLUETOOTH_CONNECT);
        } else {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH) != PackageManager.PERMISSION_GRANTED) need.add(Manifest.permission.BLUETOOTH);
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_ADMIN) != PackageManager.PERMISSION_GRANTED) need.add(Manifest.permission.BLUETOOTH_ADMIN);
        }
        if (!need.isEmpty()) {
            ActivityCompat.requestPermissions(this, need.toArray(new String[0]), REQ_PERMS_BLE);
            return false;
        }
        return true;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQ_PERMS_BLE) {
            boolean ok = true;
            for (int r : grantResults) {
                if (r != PackageManager.PERMISSION_GRANTED) { ok = false; break; }
            }
            if (ok) startScan(); else Toast.makeText(this, "Разрешения BLE не предоставлены", Toast.LENGTH_SHORT).show();
        }
    }

    private final ScanCallback scanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, @NonNull ScanResult result) {
            BluetoothDevice d = result.getDevice();
            if (d == null || d.getAddress() == null) return;
            devicesAdapter.addOrUpdate(d, result.getRssi());
        }
    };

    private void saveAndExit() {
        try {
            int udpPort = parseInt(etUdpPort.getText().toString().trim(), 10110, 1, 65535);
            settingsManager.setUDPPort(udpPort);
            settingsManager.setUDPEnabled(swUdpEnabled.isChecked());

            settingsManager.setBLEEnabled(swBleEnabled.isChecked());
            settingsManager.setBLEDeviceMac(etBleMac.getText().toString().trim());

            settingsManager.setBleUdpBridgeEnabled(swBleBridgeEnabled.isChecked());
            settingsManager.setBleUdpBridgeHost(etBleBridgeHost.getText().toString().trim());
            int brPort = parseInt(etBleBridgePort.getText().toString().trim(), 10110, 1, 65535);
            settingsManager.setBleUdpBridgePort(brPort);

            Toast.makeText(this, "Настройки сохранены", Toast.LENGTH_SHORT).show();
            finish();
        } catch (Exception e) {
            Log.e(TAG, "Ошибка сохранения: " + e.getMessage(), e);
            Toast.makeText(this, "Ошибка сохранения настроек", Toast.LENGTH_SHORT).show();
        }
    }

    private int parseInt(String s, int def, int min, int max) {
        try {
            int v = Integer.parseInt(s);
            if (v < min || v > max) return def;
            return v;
        } catch (Exception e) {
            return def;
        }
    }

    // Recycler adapter
    private static class DevicesAdapter extends RecyclerView.Adapter<DevicesAdapter.VH> {
        interface OnClick { void onClick(BluetoothDevice d); }
        private final List<Item> items = new ArrayList<>();
        private final OnClick onClick;
        DevicesAdapter(OnClick onClick) { this.onClick = onClick; }

        static class Item { BluetoothDevice d; int rssi; }

        static class VH extends RecyclerView.ViewHolder {
            TextView tvName; TextView tvMac; TextView tvRssi;
            VH(@NonNull View itemView) {
                super(itemView);
                tvName = itemView.findViewById(android.R.id.text1);
                tvMac = itemView.findViewById(android.R.id.text2);
                tvRssi = itemView.findViewById(R.id.text3);
            }
        }

        @NonNull
        @Override
        public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_ble_device, parent, false);
            return new VH(v);
        }

        @Override
        public void onBindViewHolder(@NonNull VH holder, int position) {
            Item it = items.get(position);
            String name = it.d.getName();
            holder.tvName.setText(name != null ? name : "(без имени)");
            holder.tvMac.setText(it.d.getAddress());
            holder.tvRssi.setText("RSSI: " + it.rssi);
            holder.itemView.setOnClickListener(v -> onClick.onClick(it.d));
        }

        @Override
        public int getItemCount() { return items.size(); }

        void clear() { items.clear(); notifyDataSetChanged(); }

        void addOrUpdate(BluetoothDevice d, int rssi) {
            for (Item it : items) {
                if (it.d.getAddress().equals(d.getAddress())) { it.rssi = rssi; notifyDataSetChanged(); return; }
            }
            Item it = new Item(); it.d = d; it.rssi = rssi; items.add(it); notifyDataSetChanged();
        }
    }
}
