import { useState, useEffect } from "react";
import { useWebSocketEvent } from "../hooks/useWebSocket";

interface FirmwareInfo {
  bootrom_version: string;
  os_version: string;
  client_version: string;
  compatible: boolean;
  needs_upgrade: boolean;
  needs_downgrade: boolean;
}

interface Device {
  device_id: string;
  device_path: string;
  serial_number: string | null;
  friendly_name: string | null;
  usb_vid: string;
  usb_pid: string;
  status: "connected" | "disconnected" | "in_use" | "error" | "version_mismatch" | "flashing" | "disabled";
  firmware_info: FirmwareInfo | null;
  session_id: string | null;
  last_seen: string;
}

interface FlashProgress {
  device_id: string;
  status: "starting" | "bootrom" | "fullimage" | "verifying" | "complete" | "error";
  progress: number;
  message: string;
}

interface DeviceSelectorProps {
  selectedDeviceId: string | null;
  onDeviceSelect: (deviceId: string) => void;
  showIdentifyButton?: boolean;
  autoSelectSingle?: boolean;
}

export default function DeviceSelector({
  selectedDeviceId,
  onDeviceSelect,
  showIdentifyButton = true,
  autoSelectSingle = true,
}: DeviceSelectorProps) {
  const [devices, setDevices] = useState<Device[]>([]);
  const [loading, setLoading] = useState(true);
  const [identifying, setIdentifying] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);

  // Flash-related state
  const [flashProgress, setFlashProgress] = useState<FlashProgress | null>(null);
  const [showFlashConfirm, setShowFlashConfirm] = useState<string | null>(null);
  const [flashing, setFlashing] = useState<string | null>(null);
  const [flashError, setFlashError] = useState<string | null>(null);

  // Subscribe to flash progress events
  useWebSocketEvent("pm3_flash_progress", (data) => {
    const progress = data as FlashProgress;
    setFlashProgress(progress);

    // Clear flashing state on complete or error
    if (progress.status === "complete" || progress.status === "error") {
      setFlashing(null);
      if (progress.status === "error") {
        setFlashError(progress.message);
      }
      // Clear progress after a delay
      setTimeout(() => setFlashProgress(null), 5000);
    }
  });

  // Fetch devices from API
  const fetchDevices = async () => {
    try {
      const response = await fetch("/api/pm3/devices");
      if (!response.ok) {
        throw new Error(`Failed to fetch devices: ${response.statusText}`);
      }
      const data = await response.json();

      // API returns {devices: [...]} directly (no success field)
      const deviceList = data.devices || [];
      setDevices(deviceList);

      // Auto-select single device if enabled
      if (autoSelectSingle && deviceList.length === 1 && !selectedDeviceId) {
        const device = deviceList[0];
        if (device.status === "connected") {
          onDeviceSelect(device.device_id);
        }
      }
      setError(null);
    } catch (err) {
      console.error("Error fetching devices:", err);
      setError(err instanceof Error ? err.message : "Failed to fetch devices");
      setDevices([]);
    } finally {
      setLoading(false);
    }
  };

  // Fetch devices on mount and set up polling
  useEffect(() => {
    fetchDevices();
    const interval = setInterval(fetchDevices, 5000); // Poll every 5 seconds
    return () => clearInterval(interval);
  }, []);

  // Handle device identification (LED blinking)
  const handleIdentify = async (deviceId: string) => {
    setIdentifying(deviceId);
    try {
      const response = await fetch(`/api/pm3/devices/${deviceId}/identify`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ duration: 2000 }),
      });

      if (!response.ok) {
        throw new Error("Failed to identify device");
      }

      // Keep identifying state for duration of LED blink
      setTimeout(() => setIdentifying(null), 2100);
    } catch (err) {
      console.error("Error identifying device:", err);
      setIdentifying(null);
    }
  };

  // Handle firmware flash
  const handleFlash = async (deviceId: string) => {
    setShowFlashConfirm(null);
    setFlashing(deviceId);
    setFlashError(null);

    try {
      const response = await fetch(`/api/pm3/devices/${deviceId}/flash`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ confirm: true }),
      });

      if (!response.ok) {
        const errorData = await response.json();
        throw new Error(errorData.detail || "Flash request failed");
      }

      // Flash started - progress will come via WebSocket
    } catch (err) {
      console.error("Error flashing device:", err);
      setFlashing(null);
      setFlashError(err instanceof Error ? err.message : "Flash failed");
    }
  };

  // Get status color
  const getStatusColor = (device: Device): string => {
    switch (device.status) {
      case "connected":
        return "var(--color-success)";
      case "in_use":
        return "var(--color-warning)";
      case "version_mismatch":
      case "disabled":
        return "var(--color-warning)";
      case "error":
      case "disconnected":
        return "var(--color-error)";
      case "flashing":
        return "var(--color-info)";
      default:
        return "var(--color-border)";
    }
  };

  // Get status text
  const getStatusText = (device: Device): string => {
    switch (device.status) {
      case "connected":
        return "Connected";
      case "in_use":
        return "In Use";
      case "version_mismatch":
        return "Version Mismatch";
      case "disabled":
        return "Disabled";
      case "error":
        return "Error";
      case "disconnected":
        return "Disconnected";
      case "flashing":
        return "Flashing";
      default:
        return "Unknown";
    }
  };

  // Check if device is selectable
  const isDeviceSelectable = (device: Device): boolean => {
    return (
      device.status === "connected" ||
      (device.status === "in_use" && device.device_id === selectedDeviceId)
    );
  };

  // Get display name for device
  const getDeviceName = (device: Device): string => {
    return device.friendly_name || device.device_path;
  };

  if (loading) {
    return (
      <div className="card">
        <h3 className="card-title">
          <span style={{ color: "var(--color-primary)" }}>📡</span> Proxmark3 Devices
        </h3>
        <div style={{ textAlign: "center", padding: "var(--space-6)" }}>
          <span className="spinner"></span>
          <p className="text-muted" style={{ marginTop: "var(--space-3)" }}>
            Detecting devices...
          </p>
        </div>
      </div>
    );
  }

  if (error) {
    return (
      <div className="card" style={{ borderColor: "var(--color-error)" }}>
        <h3 className="card-title">
          <span style={{ color: "var(--color-error)" }}>⚠</span> Device Detection Error
        </h3>
        <p className="text-muted">{error}</p>
        <button
          className="btn btn-secondary"
          style={{ marginTop: "var(--space-3)" }}
          onClick={fetchDevices}
        >
          Retry
        </button>
      </div>
    );
  }

  if (devices.length === 0) {
    return (
      <div className="card">
        <h3 className="card-title">
          <span style={{ color: "var(--color-primary)" }}>📡</span> Proxmark3 Devices
        </h3>
        <div style={{ textAlign: "center", padding: "var(--space-6)" }}>
          <div style={{ fontSize: "3rem", marginBottom: "var(--space-3)", opacity: 0.5 }}>
            🔌
          </div>
          <p className="text-secondary" style={{ marginBottom: "var(--space-2)" }}>
            No Proxmark3 devices detected
          </p>
          <p className="text-muted" style={{ fontSize: "0.875rem" }}>
            Connect a Proxmark3 device via USB to get started
          </p>
        </div>
      </div>
    );
  }

  const confirmDevice = showFlashConfirm ? devices.find(d => d.device_id === showFlashConfirm) : null;

  return (
    <div className="card">
      <h3 className="card-title">
        <span style={{ color: "var(--color-primary)" }}>📡</span> Proxmark3 Devices ({devices.length})
      </h3>

      {/* Flash Error Alert */}
      {flashError && (
        <div
          style={{
            marginBottom: "var(--space-3)",
            padding: "var(--space-3)",
            background: "rgba(var(--color-error-rgb), 0.1)",
            borderLeft: "3px solid var(--color-error)",
            borderRadius: "var(--radius)",
          }}
        >
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
            <span>
              <strong>Flash Error:</strong> {flashError}
            </span>
            <button
              className="btn btn-secondary"
              style={{ padding: "var(--space-1) var(--space-2)", fontSize: "0.75rem" }}
              onClick={() => setFlashError(null)}
            >
              Dismiss
            </button>
          </div>
        </div>
      )}

      <div style={{ display: "flex", flexDirection: "column", gap: "var(--space-3)" }}>
        {devices.map((device) => {
          const isSelected = selectedDeviceId === device.device_id;
          const isSelectable = isDeviceSelectable(device);
          const statusColor = getStatusColor(device);
          const isFlashing = device.status === "flashing" || flashing === device.device_id;
          const deviceFlashProgress = flashProgress?.device_id === device.device_id ? flashProgress : null;

          return (
            <div
              key={device.device_id}
              style={{
                padding: "var(--space-3)",
                border: "2px solid",
                borderColor: isSelected ? "var(--color-primary)" : statusColor,
                borderRadius: "var(--radius)",
                cursor: isSelectable && !isFlashing ? "pointer" : "not-allowed",
                opacity: isSelectable || isFlashing ? 1 : 0.6,
                transition: "all 150ms ease",
                background: isSelected ? "rgba(var(--color-primary-rgb), 0.05)" : "transparent",
                position: "relative",
              }}
              onClick={() => {
                if (isSelectable && !isSelected && !isFlashing) {
                  onDeviceSelect(device.device_id);
                }
              }}
            >
              {/* Flash Progress Overlay */}
              {isFlashing && deviceFlashProgress && (
                <div
                  style={{
                    position: "absolute",
                    top: 0,
                    left: 0,
                    right: 0,
                    bottom: 0,
                    background: "rgba(var(--color-bg-rgb), 0.8)",
                    borderRadius: "var(--radius)",
                    display: "flex",
                    flexDirection: "column",
                    justifyContent: "center",
                    alignItems: "center",
                    zIndex: 10,
                    padding: "var(--space-4)",
                  }}
                >
                  <div style={{ color: "var(--color-info)", fontSize: "2rem", marginBottom: "var(--space-2)" }}>
                    {deviceFlashProgress.status === "complete" ? "✓" : deviceFlashProgress.status === "error" ? "✗" : "⚡"}
                  </div>
                  <div style={{ color: "white", fontWeight: 600, marginBottom: "var(--space-2)" }}>
                    {deviceFlashProgress.status === "complete" ? "Flash Complete" :
                     deviceFlashProgress.status === "error" ? "Flash Failed" : "Flashing Firmware..."}
                  </div>
                  <div style={{ width: "100%", marginBottom: "var(--space-2)" }}>
                    <div
                      style={{
                        height: "8px",
                        background: "rgba(255,255,255,0.2)",
                        borderRadius: "4px",
                        overflow: "hidden",
                      }}
                    >
                      <div
                        style={{
                          height: "100%",
                          width: `${deviceFlashProgress.progress}%`,
                          background: deviceFlashProgress.status === "error" ? "var(--color-error)" :
                                     deviceFlashProgress.status === "complete" ? "var(--color-success)" : "var(--color-info)",
                          transition: "width 300ms ease",
                        }}
                      />
                    </div>
                  </div>
                  <div style={{ color: "rgba(255,255,255,0.7)", fontSize: "0.875rem", textAlign: "center" }}>
                    {deviceFlashProgress.message}
                  </div>
                  <div style={{ color: "rgba(255,255,255,0.5)", fontSize: "0.75rem", marginTop: "var(--space-1)" }}>
                    {deviceFlashProgress.progress}%
                  </div>
                </div>
              )}

              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: "var(--space-3)" }}>
                {/* Device Info */}
                <div style={{ flex: 1, minWidth: 0 }}>
                  {/* Device Name */}
                  <div style={{ fontWeight: 600, fontSize: "1.1rem", marginBottom: "var(--space-1)" }}>
                    {isSelected && (
                      <span style={{ color: "var(--color-primary)", marginRight: "var(--space-2)" }}>
                        ▸
                      </span>
                    )}
                    {getDeviceName(device)}
                  </div>

                  {/* Device Path & Serial */}
                  <div style={{ fontSize: "0.875rem", color: "var(--color-text-muted)", marginBottom: "var(--space-2)" }}>
                    <span style={{ fontFamily: "var(--font-mono)" }}>{device.device_path}</span>
                    {device.serial_number && (
                      <>
                        {" • "}
                        <span>SN: {device.serial_number}</span>
                      </>
                    )}
                  </div>

                  {/* Status & Firmware Version */}
                  <div style={{ display: "flex", flexWrap: "wrap", gap: "var(--space-2)", alignItems: "center" }}>
                    <span
                      className={`badge ${
                        device.status === "connected"
                          ? "badge-success"
                          : device.status === "error" || device.status === "disconnected"
                          ? "badge-error"
                          : device.status === "flashing"
                          ? "badge-info"
                          : "badge-warning"
                      }`}
                    >
                      <span aria-hidden="true">●</span>
                      {getStatusText(device)}
                    </span>

                    {device.firmware_info && (
                      <span className="text-muted" style={{ fontSize: "0.75rem" }}>
                        {device.firmware_info.os_version}
                      </span>
                    )}

                    {device.status === "in_use" && device.device_id !== selectedDeviceId && (
                      <span className="text-muted" style={{ fontSize: "0.75rem" }}>
                        🔒 Session Active
                      </span>
                    )}
                  </div>

                  {/* Version Mismatch Warning with Flash Button */}
                  {device.firmware_info && !device.firmware_info.compatible && device.status !== "flashing" && (
                    <div
                      style={{
                        marginTop: "var(--space-2)",
                        padding: "var(--space-2)",
                        background: "rgba(var(--color-warning-rgb), 0.1)",
                        borderLeft: "3px solid var(--color-warning)",
                        borderRadius: "var(--radius)",
                        fontSize: "0.75rem",
                      }}
                    >
                      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", flexWrap: "wrap", gap: "var(--space-2)" }}>
                        <div>
                          <div style={{ fontWeight: 600, marginBottom: "var(--space-1)" }}>
                            ⚠ Firmware Version Mismatch
                          </div>
                          <div className="text-muted">
                            Device: {device.firmware_info.os_version} •
                            Expected: {device.firmware_info.client_version}
                          </div>
                        </div>
                        <button
                          className="btn btn-warning"
                          style={{
                            fontSize: "0.75rem",
                            padding: "var(--space-1) var(--space-2)",
                            flexShrink: 0,
                          }}
                          onClick={(e) => {
                            e.stopPropagation();
                            setShowFlashConfirm(device.device_id);
                          }}
                          disabled={flashing !== null}
                        >
                          Flash Firmware
                        </button>
                      </div>
                    </div>
                  )}
                </div>

                {/* Identify Button */}
                {showIdentifyButton && device.status === "connected" && !isFlashing && (
                  <button
                    className="btn btn-secondary"
                    style={{
                      fontSize: "0.875rem",
                      padding: "var(--space-2) var(--space-3)",
                      minWidth: "44px",
                      flexShrink: 0,
                    }}
                    onClick={(e) => {
                      e.stopPropagation();
                      handleIdentify(device.device_id);
                    }}
                    disabled={identifying === device.device_id}
                    aria-label="Identify device with LED blink"
                  >
                    {identifying === device.device_id ? (
                      <>
                        <span className="spinner"></span>
                        <span>Blinking...</span>
                      </>
                    ) : (
                      <>
                        <span>💡</span>
                        <span>Identify</span>
                      </>
                    )}
                  </button>
                )}
              </div>
            </div>
          );
        })}
      </div>

      {/* Selection Info */}
      {selectedDeviceId && (
        <div
          style={{
            marginTop: "var(--space-4)",
            padding: "var(--space-3)",
            background: "var(--color-bg)",
            borderRadius: "var(--radius)",
            fontSize: "0.875rem",
          }}
        >
          <span style={{ color: "var(--color-success)" }}>✓</span> Selected device will be used for all commands
        </div>
      )}

      {/* Flash Confirmation Dialog */}
      {showFlashConfirm && confirmDevice && (
        <div
          style={{
            position: "fixed",
            top: 0,
            left: 0,
            right: 0,
            bottom: 0,
            background: "rgba(var(--color-bg-rgb), 0.75)",
            display: "flex",
            justifyContent: "center",
            alignItems: "center",
            zIndex: 1000,
          }}
          onClick={() => setShowFlashConfirm(null)}
        >
          <div
            style={{
              background: "var(--color-card)",
              borderRadius: "var(--radius)",
              padding: "var(--space-6)",
              maxWidth: "450px",
              width: "90%",
              boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.5)",
            }}
            onClick={(e) => e.stopPropagation()}
          >
            <h3 style={{ marginTop: 0, marginBottom: "var(--space-4)" }}>
              <span style={{ color: "var(--color-warning)" }}>⚡</span> Flash Firmware
            </h3>

            <p style={{ marginBottom: "var(--space-4)" }}>
              You are about to flash firmware to this device. This process will:
            </p>

            <ul style={{ marginBottom: "var(--space-4)", paddingLeft: "var(--space-4)" }}>
              <li>Update bootrom and fullimage</li>
              <li>Make the device temporarily unavailable</li>
              <li>Take approximately 1-2 minutes</li>
            </ul>

            <div
              style={{
                background: "var(--color-bg)",
                borderRadius: "var(--radius)",
                padding: "var(--space-3)",
                marginBottom: "var(--space-4)",
                fontSize: "0.875rem",
              }}
            >
              <div style={{ marginBottom: "var(--space-2)" }}>
                <strong>Device:</strong> {getDeviceName(confirmDevice)}
              </div>
              <div style={{ marginBottom: "var(--space-2)" }}>
                <strong>Path:</strong> {confirmDevice.device_path}
              </div>
              {confirmDevice.firmware_info && (
                <>
                  <div style={{ marginBottom: "var(--space-2)" }}>
                    <strong>Current:</strong> {confirmDevice.firmware_info.os_version}
                  </div>
                  <div>
                    <strong>Target:</strong> {confirmDevice.firmware_info.client_version}
                  </div>
                </>
              )}
            </div>

            <div
              style={{
                background: "rgba(var(--color-error-rgb), 0.1)",
                borderLeft: "3px solid var(--color-error)",
                borderRadius: "var(--radius)",
                padding: "var(--space-3)",
                marginBottom: "var(--space-4)",
                fontSize: "0.875rem",
              }}
            >
              <strong>Warning:</strong> Do not disconnect the device during flashing.
              Interruption may require recovery mode.
            </div>

            <div style={{ display: "flex", gap: "var(--space-3)", justifyContent: "flex-end" }}>
              <button
                className="btn btn-secondary"
                onClick={() => setShowFlashConfirm(null)}
              >
                Cancel
              </button>
              <button
                className="btn btn-warning"
                onClick={() => handleFlash(showFlashConfirm)}
              >
                Flash Firmware
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
