import {
  useEffect,
  useMemo,
  useRef,
  useState,
} from 'react';
import { invoke } from '@tauri-apps/api/core';

import {
  AlertTriangle,
  CheckCircle2,
  Cpu,
  FileUp,
  Network,
  PlugZap,
  RefreshCw,
  Rocket,
  Search,
  ShieldAlert,
  Terminal,
  UploadCloud,
  Wifi,
} from 'lucide-react';

import { Badge } from '@/components/ui/Badge';
import { Button } from '@/components/ui/Button';
import { Card } from '@/components/ui/Card';

import { addActivityLog } from '@/services/activityLogService';
import { vpnApi } from '@/services/vpnApi';

type ProvisioningMode =
  | 'full'
  | 'provision_only';

type WorkflowStep =
  | 'DETECT_ROUTER'
  | 'UPLOAD_FIRMWARE'
  | 'FLASH_FIRMWARE'
  | 'WAIT_REBOOT'
  | 'RECONNECT_ROUTER'
  | 'UPLOAD_PROVISIONING'
  | 'RUN_PROVISIONING'
  | 'REGISTER_PEER';

type StepStatus =
  | 'pending'
  | 'active'
  | 'done'
  | 'blocked';

type DetectionStatus =
  | 'idle'
  | 'checking'
  | 'reachable'
  | 'ssh_ok'
  | 'auth_required'
  | 'stale_host_key'
  | 'failed'
  | 'flashing'
  | 'waiting_reboot'
  | 'reconnecting';

type RouterEnvForm = {
  routerId: string;
  hostname: string;
  wgIp: string;
  rootPassword: string;
};

const routerPresets = [
  {
    ip: '192.168.1.1',
    label: 'Fábrica/predefinido',
    password: '',
  },
  {
    ip: '198.51.100.1',
    label: 'LAN provisionada',
    password: 'litoralr',
  },
];

const FLASH_SECONDS = 300;
const PROVISION_SECONDS = 90;

const stopPhrase = 'PARAR PROVISIONAMENTO';

const workflowSteps: Array<{
  id: WorkflowStep;
  title: string;
  description: string;
  icon: typeof Search;
}> = [
    {
      id: 'DETECT_ROUTER',
      title: 'Detetar Router',
      description: 'Ping e inspeção do router via SSH.',
      icon: Search,
    },
    {
      id: 'UPLOAD_FIRMWARE',
      title: 'Enviar Firmware',
      description: 'Copiar imagem de firmware para /tmp.',
      icon: UploadCloud,
    },
    {
      id: 'FLASH_FIRMWARE',
      title: 'Gravar Firmware',
      description: 'Executar sysupgrade -n /tmp/firmware.bin.',
      icon: Cpu,
    },
    {
      id: 'WAIT_REBOOT',
      title: 'Aguardar Reinício',
      description: 'Bloquear ações enquanto o router reinicia.',
      icon: RefreshCw,
    },
    {
      id: 'RECONNECT_ROUTER',
      title: 'Reconectar Router',
      description: 'Reconectar Ethernet e aguardar SSH.',
      icon: PlugZap,
    },
    {
      id: 'UPLOAD_PROVISIONING',
      title: 'Enviar Pacote',
      description: 'Copiar router.env e provision.sh.',
      icon: FileUp,
    },
    {
      id: 'RUN_PROVISIONING',
      title: 'Executar Provisionamento',
      description: 'Executar script de configuração no router.',
      icon: Terminal,
    },
    {
      id: 'REGISTER_PEER',
      title: 'Registar Peer VPS',
      description: 'Aplicar peer WireGuard na VPS.',
      icon: Network,
    },
  ];

const scrollClass =
  '[scrollbar-width:thin] [scrollbar-color:rgba(59,130,246,0.45)_transparent] [&::-webkit-scrollbar]:w-2 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-blue-500/30 hover:[&::-webkit-scrollbar-thumb]:bg-blue-500/50';

function statusTone(status: DetectionStatus) {
  if (
    status === 'reachable' ||
    status === 'ssh_ok'
  ) {
    return 'green';
  }

  if (
    status === 'auth_required' ||
    status === 'stale_host_key' ||
    status === 'flashing' ||
    status === 'waiting_reboot' ||
    status === 'reconnecting'
  ) {
    return 'purple';
  }

  if (status === 'failed') {
    return 'red';
  }

  return 'blue';
}

function statusLabel(status: DetectionStatus) {
  const labels: Record<DetectionStatus, string> = {
    idle: 'inativo',
    checking: 'a verificar',
    reachable: 'acessível',
    ssh_ok: 'ssh ok',
    auth_required: 'autenticação necessária',
    stale_host_key: 'chave SSH antiga',
    failed: 'falhou',
    flashing: 'a gravar firmware',
    waiting_reboot: 'a aguardar reinício',
    reconnecting: 'a reconectar',
  };

  return labels[status];
}

function formatSeconds(totalSeconds: number) {
  const minutes = Math.floor(totalSeconds / 60);
  const seconds = totalSeconds % 60;

  return `${minutes}:${String(seconds).padStart(2, '0')}`;
}

function defaultRouterEnv(): RouterEnvForm {
  return {
    routerId: '',
    hostname: '',
    wgIp: '',
    rootPassword: 'litoralr',
  };
}

function buildRouterEnv(form: RouterEnvForm) {
  return [
    `ROUTER_ID=${form.routerId}`,
    `HOSTNAME=${form.hostname}`,
    '',
    'LAN_IP=198.51.100.1',
    'LAN_NETMASK=255.255.255.0',
    '',
    `WG_IP=${form.wgIp}`,
    'WG_CIDR=32',
    'WG_SERVER_HOST=146.59.230.190',
    'WG_SERVER_PORT=4999',
    'WG_SERVER_PUBLIC_KEY=eSe9hH/X1tcAqGo09hDHvOXmy6o6NPk5sPwCzMXE7kc=',
    '',
    'CONTROLLER_IP=198.51.100.10',
    'PLC_IP=198.51.100.50',
    '',
    `ROOT_PASSWORD=${form.rootPassword.trim() || 'litoralr'}`,
    '',
  ].join('\n');
}

export function ProvisioningWizard() {
  const [provisioningMode, setProvisioningMode] =
    useState<ProvisioningMode>('full');

  const [selectedIp, setSelectedIp] =
    useState(routerPresets[0].ip);

  const [customIp, setCustomIp] = useState('');
  const [routerPassword, setRouterPassword] =
    useState(routerPresets[0].password);
  const [customPassword, setCustomPassword] =
    useState('');

  const [status, setStatus] =
    useState<DetectionStatus>('idle');

  const [activeStep, setActiveStep] =
    useState<WorkflowStep>('DETECT_ROUTER');

  const [completedSteps, setCompletedSteps] =
    useState<WorkflowStep[]>([]);

  const [routerInfo, setRouterInfo] =
    useState('');

  const [log, setLog] = useState<string[]>([]);

  const [confirmFlashOpen, setConfirmFlashOpen] =
    useState(false);

  const [flashOverlayOpen, setFlashOverlayOpen] =
    useState(false);

  const [flashSecondsRemaining, setFlashSecondsRemaining] =
    useState(FLASH_SECONDS);

  const [isReconnecting, setIsReconnecting] =
    useState(false);

  const [envModalOpen, setEnvModalOpen] =
    useState(false);

  const [routerEnv, setRouterEnv] =
    useState<RouterEnvForm>(defaultRouterEnv());

  const [stopConfirmOpen, setStopConfirmOpen] =
    useState(false);

  const [stopConfirmText, setStopConfirmText] =
    useState('');

  const flashCompletionHandledRef =
    useRef(false);

  const [provisionOverlayOpen, setProvisionOverlayOpen] =
    useState(false);

  const [provisionSecondsRemaining, setProvisionSecondsRemaining] =
    useState(PROVISION_SECONDS);

  const [isActionRunning, setIsActionRunning] =
    useState(false);

  const [setupCompleteOpen, setSetupCompleteOpen] =
    useState(false);

  const effectivePassword = customPassword.trim() || routerPassword;

  const provisioningStarted =
    activeStep !== 'DETECT_ROUTER' ||
    completedSteps.length > 0 ||
    status === 'flashing' ||
    status === 'waiting_reboot' ||
    status === 'reconnecting';

  const controlsLocked =
    provisioningStarted ||
    isReconnecting ||
    isActionRunning;

  const canContinue =
    status === 'ssh_ok' ||
    completedSteps.includes('UPLOAD_FIRMWARE') ||
    activeStep === 'UPLOAD_PROVISIONING' ||
    activeStep === 'RUN_PROVISIONING' ||
    activeStep === 'REGISTER_PEER';

  const visibleWorkflowSteps = useMemo(() => {
    if (provisioningMode === 'full') {
      return workflowSteps;
    }

    return workflowSteps.filter(
      (step) =>
        ![
          'UPLOAD_FIRMWARE',
          'FLASH_FIRMWARE',
          'WAIT_REBOOT',
          'RECONNECT_ROUTER',
        ].includes(step.id),
    );
  }, [provisioningMode]);

  const flashProgress =
    ((FLASH_SECONDS - flashSecondsRemaining) /
      FLASH_SECONDS) *
    100;

  const workflowState = useMemo(() => {
    return visibleWorkflowSteps.map((step) => {
      let stepStatus: StepStatus = 'pending';

      if (completedSteps.includes(step.id)) {
        stepStatus = 'done';
      } else if (step.id === activeStep) {
        stepStatus = 'active';
      }

      if (
        !canContinue &&
        step.id !== 'DETECT_ROUTER'
      ) {
        stepStatus = 'blocked';
      }

      return {
        ...step,
        status: stepStatus,
      };
    });
  }, [
    activeStep,
    completedSteps,
    canContinue,
    visibleWorkflowSteps,
  ]);

  function addLog(
    message: string,
    level:
      | 'info'
      | 'success'
      | 'warning'
      | 'error' = 'info',
  ) {
    setLog((currentLog) => [
      `${new Date().toLocaleTimeString()}  ${message}`,
      ...currentLog,
    ]);

    addActivityLog({
      level,
      source: 'desktop',
      action: activeStep,
      message,
      routerIp: selectedIp,
    });
  }

  function resetProvisioning(shouldLog = true) {
    setProvisioningMode('full');
    setSelectedIp(routerPresets[0].ip);
    setRouterPassword(routerPresets[0].password);
    setCustomIp('');
    setCustomPassword('');

    setActiveStep('DETECT_ROUTER');
    setCompletedSteps([]);
    setStatus('idle');
    setRouterInfo('');
    setIsReconnecting(false);
    setIsActionRunning(false);

    setFlashOverlayOpen(false);
    setConfirmFlashOpen(false);
    setProvisionOverlayOpen(false);
    setEnvModalOpen(false);
    setStopConfirmOpen(false);
    setStopConfirmText('');
    setSetupCompleteOpen(false);

    setRouterEnv(defaultRouterEnv());

    flashCompletionHandledRef.current = false;

    if (shouldLog) {
      addLog(
        'O fluxo de provisionamento foi reposto.',
        'warning',
      );
    }
  }

  function finishProvisioning() {
    resetProvisioning(false);

    setLog((currentLog) => [
      `${new Date().toLocaleTimeString()}  Configuração do router concluída com sucesso. Pronto para o próximo router.`,
      ...currentLog,
    ]);
  }

  useEffect(() => {
    if (!flashOverlayOpen) {
      return;
    }

    const intervalId = window.setInterval(() => {
      setFlashSecondsRemaining((current) => {
        if (current <= 1) {
          window.clearInterval(intervalId);

          if (!flashCompletionHandledRef.current) {
            flashCompletionHandledRef.current = true;

            setFlashOverlayOpen(false);
            setStatus('waiting_reboot');

            setCompletedSteps((currentSteps) => [
              ...new Set([
                ...currentSteps,
                'FLASH_FIRMWARE' as WorkflowStep,
                'WAIT_REBOOT' as WorkflowStep,
              ]),
            ]);

            setSelectedIp(routerPresets[0].ip);
            setRouterPassword(routerPresets[0].password);
            setCustomIp('');
            setCustomPassword('');

            setActiveStep('RECONNECT_ROUTER');

            addLog(
              'Janela de espera do flash concluída. Volte a ligar o cabo Ethernet se necessário e continue com a verificação de reconexão.',
              'success',
            );
          }

          return 0;
        }

        return current - 1;
      });
    }, 1000);

    return () => {
      window.clearInterval(intervalId);
    };
  }, [flashOverlayOpen]);

  useEffect(() => {
    if (!provisionOverlayOpen) {
      return;
    }

    const intervalId = window.setInterval(() => {
      setProvisionSecondsRemaining((current) => {
        if (current <= 1) {
          window.clearInterval(intervalId);

          setProvisionOverlayOpen(false);

          setSelectedIp(routerPresets[1].ip);
          setRouterPassword(routerPresets[1].password);
          setCustomIp('');
          setCustomPassword('');

          setActiveStep('REGISTER_PEER');

          addLog(
            'Tempo de provisionamento concluído. Desligue e volte a ligar o Ethernet, aguarde alguns segundos e continue para verificar o WireGuard e registar o peer.',
            'warning',
          );

          return 0;
        }

        return current - 1;
      });
    }, 1000);

    return () => {
      window.clearInterval(intervalId);
    };
  }, [provisionOverlayOpen]);

  async function detectRouter() {
    if (controlsLocked) {
      addLog(
        'A deteção do router está bloqueada enquanto o provisionamento está ativo.',
        'warning',
      );
      return;
    }

    if (!selectedIp.trim()) {
      addLog(
        'Deteção do router bloqueada: nenhum IP selecionado',
        'warning',
      );
      return;
    }

    setActiveStep('DETECT_ROUTER');
    setStatus('checking');
    setRouterInfo('');

    addLog(
      `A iniciar deteção segura do router em ${selectedIp}`,
    );

    try {
      await invoke<boolean>('ping_host', {
        ip: selectedIp,
      });

      addLog(
        `Router respondeu em ${selectedIp}`,
        'success',
      );

      try {
        const info = await invoke<string>(
          'probe_router_ssh',
          {
            ip: selectedIp,
          },
        );

        setRouterInfo(info);
        setStatus('ssh_ok');
        setCompletedSteps(['DETECT_ROUTER']);

        setActiveStep(
          provisioningMode === 'full'
            ? 'UPLOAD_FIRMWARE'
            : 'UPLOAD_PROVISIONING',
        );

        addLog(
          `Autenticação SSH por chave concluída com sucesso em ${selectedIp}`,
          'success',
        );

        return;
      } catch (sshError) {
        const sshMessage = String(sshError);

        if (
          sshMessage.includes(
            'STALE_HOST_KEY',
          )
        ) {
          setStatus('stale_host_key');

          addLog(
            `Detetada chave SSH antiga para ${selectedIp}`,
            'warning',
          );

          return;
        }

        if (
          sshMessage.includes(
            'AUTH_REQUIRED',
          )
        ) {
          if (!effectivePassword.trim()) {
            setStatus('auth_required');

            addLog(
              'O router requer palavra-passe SSH. Introduza a palavra-passe no campo "Acesso Personalizado ao Router" e volte a detetar.',
              'warning',
            );

            return;
          }

          addLog(
            'O router requer autenticação por palavra-passe. A tentar inspeção automática...',
            'warning',
          );

          try {
            const passwordInfo =
              await invoke<string>(
                'inspect_router_with_password',
                {
                  ip: selectedIp,
                  password: effectivePassword,
                },
              );

            setRouterInfo(passwordInfo);
            setStatus('ssh_ok');
            setCompletedSteps([
              'DETECT_ROUTER',
            ]);

            setActiveStep(
              provisioningMode === 'full'
                ? 'UPLOAD_FIRMWARE'
                : 'UPLOAD_PROVISIONING',
            );

            addLog(
              `Inspeção SSH por palavra-passe concluída com sucesso em ${selectedIp}`,
              'success',
            );

            return;
          } catch (passwordError) {
            setStatus('auth_required');

            addLog(
              `Falha na autenticação por palavra-passe: ${String(
                passwordError,
              )}`,
              'error',
            );

            return;
          }
        }

        throw sshError;
      }
    } catch (error) {
      const message = String(error);

      setStatus('failed');

      addLog(
        `Falha na deteção do router: ${message}`,
        'error',
      );
    }
  }

  async function fixKnownHost() {
    if (controlsLocked) {
      addLog(
        'A limpeza de known_hosts está bloqueada enquanto o provisionamento está ativo.',
        'warning',
      );
      return;
    }

    if (!selectedIp.trim()) {
      addLog(
        'Não foi possível remover a entrada known_hosts: nenhum IP selecionado',
        'warning',
      );
      return;
    }

    try {
      addLog(
        `A remover entrada known_hosts para ${selectedIp}`,
      );

      const result = await invoke<string>(
        'remove_known_host',
        {
          ip: selectedIp,
        },
      );

      addLog(result, 'success');
      setStatus('idle');
      setCompletedSteps([]);
      setActiveStep('DETECT_ROUTER');
    } catch (error) {
      addLog(String(error), 'error');
    }
  }

  async function continueProvisioning() {
    if (isActionRunning || isReconnecting) {
      return;
    }

    setIsActionRunning(true);

    try {
      await continueProvisioningInner();
    } finally {
      setIsActionRunning(false);
    }
  }

  async function continueProvisioningInner() {
    if (activeStep === 'UPLOAD_FIRMWARE') {
      try {
        addLog(
          `A enviar firmware para ${selectedIp}:/tmp/firmware.bin`,
        );

        const result = await invoke<string>(
          'upload_firmware_to_router',
          {
            ip: selectedIp,
            password: effectivePassword,
          },
        );

        addLog(result, 'success');

        setCompletedSteps((currentSteps) => [
          ...new Set([
            ...currentSteps,
            'UPLOAD_FIRMWARE' as WorkflowStep,
          ]),
        ]);

        setActiveStep('FLASH_FIRMWARE');

        return;
      } catch (error) {
        addLog(
          `Falha no envio do firmware: ${String(error)}`,
          'error',
        );

        return;
      }
    }

    if (activeStep === 'FLASH_FIRMWARE') {
      setConfirmFlashOpen(true);
      return;
    }

    if (activeStep === 'RECONNECT_ROUTER') {
      if (isReconnecting) {
        return;
      }

      setIsReconnecting(true);
      setStatus('reconnecting');

      addLog(
        `A verificar SSH do router após flash em ${selectedIp}`,
        'warning',
      );

      for (let attempt = 1; attempt <= 30; attempt += 1) {
        try {
          addLog(`Tentativa de reconexão ${attempt}/30`);

          const info = await invoke<string>(
            'check_router_after_flash',
            {
              ip: selectedIp,
              password: effectivePassword,
            },
          );

          setRouterInfo(info);

          addLog(
            `SSH do router reconectado após flash em ${selectedIp}`,
            'success',
          );

          setCompletedSteps((currentSteps) => [
            ...new Set([
              ...currentSteps,
              'RECONNECT_ROUTER' as WorkflowStep,
            ]),
          ]);

          setStatus('ssh_ok');
          setActiveStep('UPLOAD_PROVISIONING');
          setIsReconnecting(false);

          return;
        } catch (error) {
          const message = String(error);
          const lowered = message.toLowerCase();

          addLog(
            `Tentativa de reconexão ${attempt}/30 falhou: ${message}`,
            'warning',
          );

          if (
            lowered.includes('auth_required') ||
            lowered.includes('permission denied') ||
            lowered.includes('publickey,password')
          ) {
            setStatus('auth_required');
            setIsReconnecting(false);

            addLog(
              'O router está acessível por SSH, mas requer palavra-passe. Introduza a palavra-passe e carregue em Continuar novamente.',
              'error',
            );

            return;
          }

          await new Promise((resolve) =>
            window.setTimeout(resolve, 5000),
          );
        }
      }

      setStatus('failed');
      setIsReconnecting(false);

      addLog(
        'Falha na reconexão do router após 30 tentativas. Volte a ligar o Ethernet e tente novamente.',
        'error',
      );

      return;
    }

    if (activeStep === 'UPLOAD_PROVISIONING') {
      await prepareRouterEnv();
      return;
    }

    if (activeStep === 'RUN_PROVISIONING') {
      setProvisionSecondsRemaining(PROVISION_SECONDS);
      setProvisionOverlayOpen(true);

      try {
        addLog(
          `A executar script de provisionamento em ${selectedIp}`,
          'warning',
        );

        const result = await invoke<string>(
          'run_provisioning',
          {
            ip: selectedIp,
            password: effectivePassword,
          },
        );

        addLog(result, 'success');
      } catch (error) {
        const message = String(error);
        const lowered = message.toLowerCase();

        const expectedProvisionDisconnect =
          lowered.includes('connection reset') ||
          lowered.includes('client_loop') ||
          lowered.includes('failed to connect to ubus') ||
          lowered.includes('disconnect') ||
          lowered.includes('broken pipe') ||
          lowered.includes('restart') ||
          lowered.includes('radio0');

        if (expectedProvisionDisconnect) {
          addLog(
            'O script de provisionamento atingiu o reinício de rede/serviços e o SSH desligou-se como esperado.',
            'warning',
          );

          addLog(message, 'info');
        } else {
          setProvisionOverlayOpen(false);

          addLog(
            `Falha no script de provisionamento: ${message}`,
            'error',
          );

          return;
        }
      }

      setCompletedSteps((currentSteps) => [
        ...new Set([
          ...currentSteps,
          'RUN_PROVISIONING' as WorkflowStep,
        ]),
      ]);

      setActiveStep('REGISTER_PEER');

      return;
    }

    if (activeStep === 'REGISTER_PEER') {
      try {
        addLog(
          `A capturar chave pública WireGuard do router em ${routerPresets[1].ip}`,
          'warning',
        );

        const publicKey = await invoke<string>(
          'capture_wireguard_public_key',
          {
            ip: routerPresets[1].ip,
            password: routerEnv.rootPassword.trim() || routerPresets[1].password,
          },
        );

        addLog(
          `Chave pública do router capturada ${publicKey.slice(0, 12)}...`,
          'success',
        );

        await vpnApi.registerPeer({
          vpnIp: routerEnv.wgIp,
          publicKey,
        });

        addLog(
          `Peer VPS ${routerEnv.wgIp} registado`,
          'success',
        );

        setCompletedSteps((currentSteps) => [
          ...new Set([
            ...currentSteps,
            'REGISTER_PEER' as WorkflowStep,
          ]),
        ]);

        setStatus('ssh_ok');
        setSetupCompleteOpen(true);

        return;
      } catch (error) {
        addLog(
          `Falha no registo do peer: ${String(error)}`,
          'error',
        );

        return;
      }
    }

    addLog(
      `O passo ${activeStep} ainda não está ligado.`,
      'warning',
    );
  }

  async function uploadProvisioningBundle() {
    if (
      !routerEnv.routerId.trim() ||
      !routerEnv.hostname.trim() ||
      !routerEnv.wgIp.trim()
    ) {
      addLog(
        'router.env não contém o ID do router, hostname ou IP WireGuard.',
        'error',
      );
      return;
    }

    try {
      const envContent = buildRouterEnv(routerEnv);

      addLog(
        `A enviar router.env e provision.sh para ${selectedIp}`,
        'warning',
      );

      const result = await invoke<string>(
        'upload_provisioning_bundle',
        {
          ip: selectedIp,
          password: effectivePassword,
          envContent,
        },
      );

      addLog(result, 'success');

      setEnvModalOpen(false);

      setCompletedSteps((currentSteps) => [
        ...new Set([
          ...currentSteps,
          'UPLOAD_PROVISIONING' as WorkflowStep,
        ]),
      ]);

      setActiveStep('RUN_PROVISIONING');
    } catch (error) {
      addLog(
        `Falha no envio do pacote de provisionamento: ${String(error)}`,
        'error',
      );
    }
  }

  async function confirmAndFlashRouter() {
    setConfirmFlashOpen(false);
    setStatus('flashing');
    setActiveStep('FLASH_FIRMWARE');

    flashCompletionHandledRef.current = false;

    setFlashSecondsRemaining(FLASH_SECONDS);
    setFlashOverlayOpen(true);

    addLog(
      'A iniciar gravação do firmware com sysupgrade -F -n /tmp/firmware.bin',
      'warning',
    );

    try {
      await invoke<string>('flash_router_sysupgrade', {
        ip: selectedIp,
        password: effectivePassword,
      });

      addLog(
        'Comando de flash submetido. A sessão SSH pode desligar; a janela de espera protegida já está ativa.',
        'success',
      );
    } catch (error) {
      const message = String(error);
      const loweredMessage = message.toLowerCase();

      if (
        loweredMessage.includes('auth_required') ||
        loweredMessage.includes('permission denied') ||
        loweredMessage.includes('publickey,password')
      ) {
        setFlashOverlayOpen(false);
        setStatus('auth_required');

        addLog(`Flash não iniciado: ${message}`, 'error');

        return;
      }

      if (
        loweredMessage.includes('device') &&
        loweredMessage.includes('not supported') &&
        loweredMessage.includes('image')
      ) {
        setFlashOverlayOpen(false);
        setStatus('failed');

        addLog(
          `Flash bloqueado por incompatibilidade de imagem: ${message}`,
          'error',
        );

        return;
      }

      if (
        loweredMessage.includes('broken pipe') ||
        loweredMessage.includes('connection reset') ||
        loweredMessage.includes('channel') ||
        loweredMessage.includes('disconnect') ||
        loweredMessage.includes('commencing upgrade') ||
        loweredMessage.includes('closing all shell sessions') ||
        loweredMessage.includes('connection failed') ||
        loweredMessage.includes('sysupgrade')
      ) {
        addLog(
          'O router aceitou o sysupgrade e desligou-se como esperado durante o flash.',
          'warning',
        );

        return;
      }

      setFlashOverlayOpen(false);
      setStatus('failed');

      addLog(
        `Falha no comando de flash antes do reinício: ${message}`,
        'error',
      );
    }
  }

  async function prepareRouterEnv() {
    const timeoutMs = 15000;

    try {
      addLog(
        'A pedir ao backend o próximo IP WireGuard disponível...',
      );

      const timeoutPromise = new Promise<never>((_, reject) => {
        window.setTimeout(() => {
          reject(
            new Error(
              `TIMEOUT: o backend não respondeu ao pedido de próximo IP WireGuard em ${timeoutMs / 1000}s`,
            ),
          );
        }, timeoutMs);
      });

      const response = await Promise.race([
        vpnApi.availableIp(),
        timeoutPromise,
      ]);

      const vpnIp = response.vpnIp;

      if (!vpnIp || typeof vpnIp !== 'string') {
        throw new Error(
          `Resposta inválida do backend ao pedir IP WireGuard: ${JSON.stringify(response)}`,
        );
      }

      const vpnParts = vpnIp.split('.');
      const routerId =
        vpnParts[vpnParts.length - 1] || '';

      if (!routerId) {
        throw new Error(
          `IP WireGuard inválido recebido do backend: ${vpnIp}`,
        );
      }

      setRouterEnv((current) => ({
        ...current,
        routerId,
        hostname: `Litoral_Regas_${routerId}`,
        wgIp: vpnIp,
      }));

      addLog(
        `Candidato a próximo IP WireGuard disponível reservado: ${vpnIp}`,
        'success',
      );

      setEnvModalOpen(true);
    } catch (error) {
      setEnvModalOpen(false);

      addLog(
        `Falha ao obter IP WireGuard disponível: ${String(error)}`,
        'error',
      );
    }
  }

  return (
    <div className="flex min-h-full flex-col">
      <div className="mb-5 flex flex-wrap items-start justify-between gap-4 rounded-3xl border border-white/10 bg-white/[0.025] px-5 py-4">
        <div className="min-w-0">
          <h1 className="text-3xl font-black tracking-tight text-white">
            Provisionamento
          </h1>

          <p className="mt-1 text-sm text-slate-400">
            Provisionamento guiado do router, desde a deteção até ao registo do peer na VPS.
          </p>
        </div>

        <div className="flex items-center gap-3">
          {provisioningStarted && (
            <Button
              type="button"
              variant="danger"
              onClick={() => setStopConfirmOpen(true)}
              disabled={
                status === 'flashing' ||
                isReconnecting ||
                isActionRunning
              }
            >
              Parar Provisionamento
            </Button>
          )}

          <Badge tone={statusTone(status)}>
            {statusLabel(status)}
          </Badge>
        </div>
      </div>

      <div className="grid gap-4 2xl:grid-cols-12">
        <Card className="2xl:col-span-5">
          <div className="mb-5 flex items-center gap-4">
            <div className="rounded-2xl bg-blue-500/10 p-3 text-blue-300">
              <Search size={24} />
            </div>

            <div className="min-w-0">
              <h2 className="text-xl font-semibold text-white">
                Ligação ao Router
              </h2>

              <p className="text-sm text-slate-400">
                Selecione o alvo e valide o SSH antes do provisionamento.
              </p>
            </div>
          </div>

          <div className="mb-4 grid gap-3 md:grid-cols-2">
            <ModeButton
              active={provisioningMode === 'full'}
              disabled={controlsLocked}
              title="Provisionamento Completo"
              description="Gravar firmware, reconectar e depois provisionar."
              onClick={() => setProvisioningMode('full')}
            />

            <ModeButton
              active={provisioningMode === 'provision_only'}
              disabled={controlsLocked}
              title="Apenas Provisionar"
              description="O router já tem firmware gravado e está estável."
              onClick={() => setProvisioningMode('provision_only')}
            />
          </div>

          <div className="grid gap-3 md:grid-cols-2">
            {routerPresets.map((preset) => {
              const active =
                selectedIp === preset.ip &&
                customIp.trim() === '';

              return (
                <button
                  key={preset.ip}
                  type="button"
                  disabled={controlsLocked}
                  onClick={() => {
                    setSelectedIp(preset.ip);
                    setRouterPassword(preset.password);
                    setCustomIp('');
                  }}
                  className={`rounded-2xl border p-4 text-left transition disabled:cursor-not-allowed disabled:opacity-60 ${active
                      ? 'border-blue-500/40 bg-blue-500/10'
                      : 'border-white/10 bg-white/[0.02] hover:border-blue-500/20 hover:bg-white/[0.04]'
                    }`}
                >
                  <Network
                    size={18}
                    className={
                      active
                        ? 'text-blue-300'
                        : 'text-slate-500'
                    }
                  />

                  <p className="mt-3 font-mono text-sm font-semibold text-white">
                    {preset.ip}
                  </p>

                  <p className="mt-1 text-xs text-slate-500">
                    {preset.label}
                  </p>

                  <p className="mt-3 text-xs text-slate-500">
                    Palavra-passe:{' '}
                    <span className="font-mono text-slate-300">
                      {preset.password || 'vazia'}
                    </span>
                  </p>
                </button>
              );
            })}

            <div
              className={`rounded-2xl border p-4 transition md:col-span-2 ${customIp.trim()
                  ? 'border-blue-500/40 bg-blue-500/10'
                  : 'border-white/10 bg-white/[0.02]'
                }`}
            >
              <div className="mb-3 flex items-center gap-3">
                <Network
                  size={18}
                  className={
                    customIp.trim()
                      ? 'text-blue-300'
                      : 'text-slate-500'
                  }
                />

                <div>
                  <p className="text-sm font-semibold text-white">
                    Acesso Personalizado ao Router
                  </p>

                  <p className="text-xs text-slate-500">
                    Use para IPs de router ou palavras-passe não padrão.
                  </p>
                </div>
              </div>

              <div className="grid gap-3 md:grid-cols-2">
                <div>
                  <label className="mb-2 block text-xs font-medium uppercase tracking-wide text-slate-500">
                    IP do Router
                  </label>

                  <input
                    disabled={controlsLocked}
                    value={customIp}
                    onChange={(event) => {
                      const value =
                        event.target.value;

                      setCustomIp(value);
                      setSelectedIp(value.trim());
                    }}
                    onFocus={() => {
                      setSelectedIp(customIp.trim());
                    }}
                    placeholder="Exemplo: 192.168.8.1"
                    className="w-full rounded-xl border border-white/10 bg-slate-950 px-3 py-2 font-mono text-sm text-white outline-none transition focus:border-blue-500/40 disabled:cursor-not-allowed disabled:opacity-60"
                  />
                </div>

                <div>
                  <label className="mb-2 block text-xs font-medium uppercase tracking-wide text-slate-500">
                    Palavra-passe SSH
                  </label>

                  <input
                    disabled={controlsLocked}
                    type="password"
                    value={customPassword}
                    onChange={(event) =>
                      setCustomPassword(
                        event.target.value,
                      )
                    }
                    onFocus={() => {
                      if (customIp.trim()) {
                        setSelectedIp(
                          customIp.trim(),
                        );
                      }
                    }}
                    placeholder="Vazio se não existir"
                    className="w-full rounded-xl border border-white/10 bg-slate-950 px-3 py-2 font-mono text-sm text-white outline-none transition focus:border-blue-500/40 disabled:cursor-not-allowed disabled:opacity-60"
                  />
                </div>
              </div>
            </div>
          </div>

          <div className="mt-4 rounded-2xl border border-white/10 bg-slate-950/70 p-4">
            <div className="flex items-start gap-4">
              <div className="rounded-2xl bg-green-500/10 p-3 text-green-300">
                <Wifi size={22} />
              </div>

              <div className="min-w-0 flex-1">
                <p className="font-semibold text-white">
                  Alvo de Deteção
                </p>

                <p className="mt-1 truncate font-mono text-sm text-slate-400">
                  root@{selectedIp || '—'}
                </p>
              </div>

              <Badge tone={statusTone(status)}>
                {statusLabel(status)}
              </Badge>
            </div>
          </div>

          <div className="mt-4 flex flex-wrap gap-3">
            <Button
              type="button"
              onClick={detectRouter}
              disabled={
                controlsLocked ||
                status === 'checking' ||
                !selectedIp.trim()
              }
            >
              <Search size={16} />
              Detetar Router
            </Button>

            <Button
              type="button"
              variant="secondary"
              onClick={fixKnownHost}
              disabled={
                controlsLocked ||
                !selectedIp.trim()
              }
            >
              <ShieldAlert size={16} />
              Corrigir Known Host
            </Button>
          </div>
        </Card>

        <Card className="2xl:col-span-7">
          <div className="mb-4 flex flex-wrap items-start justify-between gap-4">
            <div className="flex items-center gap-3">
              <div className="rounded-2xl bg-blue-500/10 p-3 text-blue-300">
                <Rocket size={22} />
              </div>

              <div>
                <h2 className="text-lg font-semibold text-white">
                  Fluxo de Provisionamento
                </h2>

                <p className="text-sm text-slate-400">
                  Sequência completa de preparação do router.
                </p>
              </div>
            </div>

            <Button
              type="button"
              onClick={continueProvisioning}
              disabled={
                !canContinue ||
                status === 'flashing' ||
                isReconnecting ||
                isActionRunning
              }
            >
              <Rocket size={16} />
              {isActionRunning
                ? 'A trabalhar...'
                : isReconnecting
                  ? 'A reconectar...'
                  : 'Continuar'}
            </Button>
          </div>

          <div className="grid gap-3 md:grid-cols-2">
            {workflowState.map((step) => (
              <WorkflowStepCard
                key={step.id}
                title={step.title}
                description={step.description}
                icon={step.icon}
                status={step.status}
              />
            ))}
          </div>
        </Card>
      </div>

      <div className="mt-4 grid gap-4 xl:grid-cols-12">
        <Card className="min-h-[260px] xl:col-span-5">
          <div className="mb-4 flex items-center gap-3">
            <div className="rounded-2xl bg-blue-500/10 p-3 text-blue-300">
              <Terminal size={22} />
            </div>

            <div>
              <h2 className="text-lg font-semibold text-white">
                Informação do Router
              </h2>

              <p className="text-sm text-slate-400">
                Saída de ubus system board.
              </p>
            </div>
          </div>

          <pre
            className={`max-h-[260px] min-h-[160px] overflow-auto whitespace-pre-wrap rounded-2xl border border-white/10 bg-slate-950 p-4 font-mono text-xs text-slate-300 ${scrollClass}`}
          >
            {routerInfo || 'Ainda não foi capturada informação do router.'}
          </pre>
        </Card>

        <Card className="min-h-[260px] xl:col-span-7">
          <h3 className="mb-2 text-sm font-semibold text-white">
            Registo Técnico
          </h3>

          <pre
            className={`max-h-[260px] min-h-[200px] overflow-auto whitespace-pre-wrap break-words rounded-xl border border-white/10 bg-slate-950/70 p-3 font-mono text-sm text-slate-300 ${scrollClass}`}
          >
            {log.join('\n') || 'Ainda não há atividade de provisionamento.'}
          </pre>
        </Card>
      </div>

      {confirmFlashOpen && (
        <ConfirmFlashModal
          selectedIp={selectedIp}
          onCancel={() => setConfirmFlashOpen(false)}
          onConfirm={confirmAndFlashRouter}
        />
      )}

      {flashOverlayOpen && (
        <FlashOverlay
          flashSecondsRemaining={flashSecondsRemaining}
          flashProgress={flashProgress}
        />
      )}

      {provisionOverlayOpen && (
        <ProvisionOverlay
          provisionSecondsRemaining={provisionSecondsRemaining}
          provisionProgress={
            ((PROVISION_SECONDS - provisionSecondsRemaining) /
              PROVISION_SECONDS) *
            100
          }
        />
      )}

      {envModalOpen && (
        <RouterEnvModal
          routerEnv={routerEnv}
          setRouterEnv={setRouterEnv}
          onCancel={() => setEnvModalOpen(false)}
          onUpload={uploadProvisioningBundle}
        />
      )}

      {stopConfirmOpen && (
        <StopProvisioningModal
          value={stopConfirmText}
          onChange={setStopConfirmText}
          onCancel={() => {
            setStopConfirmOpen(false);
            setStopConfirmText('');
          }}
          onConfirm={() => resetProvisioning(true)}
          canConfirm={stopConfirmText === stopPhrase}
        />
      )}

      {setupCompleteOpen && (
        <SetupCompleteModal
          routerId={routerEnv.routerId}
          hostname={routerEnv.hostname}
          wgIp={routerEnv.wgIp}
          onClose={finishProvisioning}
        />
      )}
    </div>
  );
}

function ModeButton({
  active,
  disabled,
  title,
  description,
  onClick,
}: {
  active: boolean;
  disabled: boolean;
  title: string;
  description: string;
  onClick: () => void;
}) {
  return (
    <button
      type="button"
      disabled={disabled}
      onClick={onClick}
      className={`rounded-2xl border p-4 text-left transition disabled:cursor-not-allowed disabled:opacity-60 ${active
          ? 'border-blue-500/40 bg-blue-500/10'
          : 'border-white/10 bg-white/[0.02] hover:border-blue-500/20 hover:bg-white/[0.04]'
        }`}
    >
      <p className="font-semibold text-white">
        {title}
      </p>

      <p className="mt-1 text-xs text-slate-500">
        {description}
      </p>
    </button>
  );
}

function RouterEnvModal({
  routerEnv,
  setRouterEnv,
  onCancel,
  onUpload,
}: {
  routerEnv: RouterEnvForm;
  setRouterEnv: React.Dispatch<
    React.SetStateAction<RouterEnvForm>
  >;
  onCancel: () => void;
  onUpload: () => void;
}) {
  function updateField(
    field: keyof RouterEnvForm,
    value: string,
  ) {
    setRouterEnv((current) => ({
      ...current,
      [field]: value,
    }));
  }

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/75 p-4 backdrop-blur-sm">
      <div className="max-h-[90vh] w-full max-w-3xl overflow-auto rounded-3xl border border-blue-500/30 bg-slate-950 p-6 shadow-2xl shadow-blue-500/10">
        <div className="mb-5 flex items-center gap-4">
          <div className="rounded-2xl bg-blue-500/10 p-3 text-blue-300">
            <FileUp size={26} />
          </div>

          <div>
            <h2 className="text-2xl font-bold text-white">
              Ambiente do Router
            </h2>

            <p className="text-sm text-slate-400">
              Valores usados para gerar router.env antes do envio.
            </p>
          </div>
        </div>

        <div className="grid gap-4 md:grid-cols-2">
          <EnvInput
            label="ID do Router"
            value={routerEnv.routerId}
            onChange={(value) => updateField('routerId', value)}
            placeholder="203"
          />

          <EnvInput
            label="Hostname"
            value={routerEnv.hostname}
            onChange={(value) => updateField('hostname', value)}
            placeholder="Litoral_Regas_203"
          />

          <EnvInput
            label="IP WireGuard"
            value={routerEnv.wgIp}
            onChange={(value) => updateField('wgIp', value)}
            placeholder="198.19.1.203"
          />

          <EnvInput
            label="Palavra-passe Root"
            value={routerEnv.rootPassword}
            onChange={(value) => updateField('rootPassword', value)}
            placeholder="litoralr"
            type="password"
          />
        </div>

        <div className="mt-5 rounded-2xl border border-white/10 bg-white/[0.02] p-4">
          <p className="text-xs font-semibold uppercase tracking-wide text-slate-500">
            Valores estáticos de router.env
          </p>

          <div className="mt-3 grid gap-3 font-mono text-xs text-slate-300 md:grid-cols-2">
            <p>LAN_IP=198.51.100.1</p>
            <p>LAN_NETMASK=255.255.255.0</p>
            <p>WG_CIDR=32</p>
            <p>WG_SERVER_HOST=146.59.230.190</p>
            <p>WG_SERVER_PORT=4999</p>
            <p>CONTROLLER_IP=198.51.100.10</p>
            <p>PLC_IP=198.51.100.50</p>
            <p className="truncate">
              WG_SERVER_PUBLIC_KEY=eSe9hH/X1tcAqGo09hDHvOXmy6o6NPk5sPwCzMXE7kc=
            </p>
          </div>
        </div>

        <div className="mt-6 flex justify-end gap-3">
          <Button type="button" variant="secondary" onClick={onCancel}>
            Cancelar
          </Button>

          <Button type="button" onClick={onUpload}>
            <FileUp size={16} />
            Enviar Pacote
          </Button>
        </div>
      </div>
    </div>
  );
}

function EnvInput({
  label,
  value,
  onChange,
  placeholder,
  type = 'text',
}: {
  label: string;
  value: string;
  onChange: (value: string) => void;
  placeholder?: string;
  type?: string;
}) {
  return (
    <div>
      <label className="mb-2 block text-xs font-medium uppercase tracking-wide text-slate-500">
        {label}
      </label>

      <input
        type={type}
        value={value}
        onChange={(event) => onChange(event.target.value)}
        placeholder={placeholder}
        className="w-full rounded-xl border border-white/10 bg-slate-950 px-3 py-2 font-mono text-sm text-white outline-none transition focus:border-blue-500/40"
      />
    </div>
  );
}

function ConfirmFlashModal({
  selectedIp,
  onCancel,
  onConfirm,
}: {
  selectedIp: string;
  onCancel: () => void;
  onConfirm: () => void;
}) {
  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/75 p-4 backdrop-blur-sm">
      <div className="w-full max-w-xl rounded-3xl border border-red-500/30 bg-slate-950 p-6 shadow-2xl shadow-red-500/10">
        <div className="flex gap-4">
          <div className="rounded-2xl bg-red-500/10 p-3 text-red-300">
            <AlertTriangle size={28} />
          </div>

          <div>
            <h2 className="text-2xl font-bold text-white">
              Confirmar Gravação do Firmware
            </h2>

            <p className="mt-3 text-sm leading-6 text-slate-300">
              Isto irá executar{' '}
              <span className="font-mono text-red-200">
                sysupgrade -n /tmp/firmware.bin
              </span>{' '}
              no router{' '}
              <span className="font-mono text-red-200">
                {selectedIp}
              </span>
              . A sessão SSH será interrompida e o router poderá ficar inacessível durante vários minutos.
            </p>

            <div className="mt-5 rounded-2xl border border-red-500/20 bg-red-500/10 p-4 text-sm text-red-100">
              Não desligue a alimentação do router. Não feche esta aplicação.
            </div>

            <div className="mt-6 flex justify-end gap-3">
              <Button type="button" variant="secondary" onClick={onCancel}>
                Cancelar
              </Button>

              <Button type="button" onClick={onConfirm} className="bg-red-500 hover:bg-red-400">
                <Cpu size={16} />
                Gravar Router
              </Button>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

function FlashOverlay({
  flashSecondsRemaining,
  flashProgress,
}: {
  flashSecondsRemaining: number;
  flashProgress: number;
}) {
  return (
    <div className="fixed inset-0 z-[60] flex items-center justify-center bg-black/85 p-4 backdrop-blur-md">
      <div className="w-full max-w-2xl rounded-3xl border border-purple-500/30 bg-slate-950 p-8 shadow-2xl shadow-purple-500/20">
        <div className="flex items-start gap-5">
          <div className="rounded-3xl bg-purple-500/10 p-4 text-purple-300">
            <RefreshCw size={34} className="animate-spin" />
          </div>

          <div className="flex-1">
            <h2 className="text-3xl font-bold text-white">
              A gravar firmware do router
            </h2>

            <p className="mt-3 leading-7 text-slate-300">
              O router está a aplicar o firmware e a reiniciar. A sessão SSH ficará indisponível temporariamente.
            </p>

            <div className="mt-6 rounded-2xl border border-white/10 bg-white/[0.03] p-5">
              <div className="mb-3 flex items-center justify-between text-sm">
                <span className="text-slate-400">
                  Janela de espera protegida
                </span>

                <span className="font-mono text-purple-200">
                  {formatSeconds(flashSecondsRemaining)}
                </span>
              </div>

              <div className="h-3 overflow-hidden rounded-full bg-slate-800">
                <div
                  className="h-full rounded-full bg-purple-400 transition-all duration-1000"
                  style={{ width: `${flashProgress}%` }}
                />
              </div>
            </div>

            <div className="mt-6 rounded-2xl border border-red-500/20 bg-red-500/10 p-4 text-sm leading-6 text-red-100">
              Não desligue a alimentação. Não feche esta aplicação. Aguarde até este ecrã terminar antes de mexer no cabo Ethernet.
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

function ProvisionOverlay({
  provisionSecondsRemaining,
  provisionProgress,
}: {
  provisionSecondsRemaining: number;
  provisionProgress: number;
}) {
  return (
    <div className="fixed inset-0 z-[60] flex items-center justify-center bg-black/85 p-4 backdrop-blur-md">
      <div className="w-full max-w-2xl rounded-3xl border border-blue-500/30 bg-slate-950 p-8 shadow-2xl shadow-blue-500/20">
        <div className="flex items-start gap-5">
          <div className="rounded-3xl bg-blue-500/10 p-4 text-blue-300">
            <RefreshCw size={34} className="animate-spin" />
          </div>

          <div className="flex-1">
            <h2 className="text-3xl font-bold text-white">
              A aplicar provisionamento do router
            </h2>

            <p className="mt-3 leading-7 text-slate-300">
              O router está a alterar definições de LAN, firewall, WireGuard, LuCI
              e palavra-passe root. O SSH ou Ethernet poderá cair durante este passo.
            </p>

            <div className="mt-6 rounded-2xl border border-white/10 bg-white/[0.03] p-5">
              <div className="mb-3 flex items-center justify-between text-sm">
                <span className="text-slate-400">
                  Janela de provisionamento protegida
                </span>

                <span className="font-mono text-blue-200">
                  {formatSeconds(provisionSecondsRemaining)}
                </span>
              </div>

              <div className="h-3 overflow-hidden rounded-full bg-slate-800">
                <div
                  className="h-full rounded-full bg-blue-400 transition-all duration-1000"
                  style={{ width: `${provisionProgress}%` }}
                />
              </div>
            </div>

            <div className="mt-6 rounded-2xl border border-yellow-500/20 bg-yellow-500/10 p-4 text-sm leading-6 text-yellow-100">
              Não desligue a alimentação. Quando este temporizador terminar, desligue e volte a ligar o cabo Ethernet,
              depois continue para verificar o WireGuard e registar o peer VPS.
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

function StopProvisioningModal({
  value,
  onChange,
  onCancel,
  onConfirm,
  canConfirm,
}: {
  value: string;
  onChange: (value: string) => void;
  onCancel: () => void;
  onConfirm: () => void;
  canConfirm: boolean;
}) {
  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/75 p-4 backdrop-blur-sm">
      <div className="w-full max-w-xl rounded-3xl border border-red-500/30 bg-slate-950 p-6 shadow-2xl shadow-red-500/10">
        <div className="flex gap-4">
          <div className="rounded-2xl bg-red-500/10 p-3 text-red-300">
            <AlertTriangle size={28} />
          </div>

          <div className="flex-1">
            <h2 className="text-2xl font-bold text-white">
              Parar Provisionamento?
            </h2>

            <p className="mt-3 text-sm leading-6 text-slate-300">
              Parar a meio do provisionamento pode deixar o router num estado parcial ou avariado. Continue apenas se souber que o estado atual do router é seguro.
            </p>

            <p className="mt-5 text-sm text-slate-400">
              Escreva{' '}
              <span className="font-mono text-red-200">
                {stopPhrase}
              </span>{' '}
              para confirmar.
            </p>

            <input
              value={value}
              onChange={(event) => onChange(event.target.value)}
              className="mt-3 w-full rounded-xl border border-red-500/20 bg-slate-950 px-3 py-2 font-mono text-sm text-white outline-none focus:border-red-400/50"
            />

            <div className="mt-6 flex justify-end gap-3">
              <Button type="button" variant="secondary" onClick={onCancel}>
                Cancelar
              </Button>

              <Button
                type="button"
                variant="danger"
                disabled={!canConfirm}
                onClick={onConfirm}
              >
                Parar Provisionamento
              </Button>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

function WorkflowStepCard({
  title,
  description,
  icon: Icon,
  status,
}: {
  title: string;
  description: string;
  icon: typeof Search;
  status: StepStatus;
}) {
  const active = status === 'active';
  const done = status === 'done';
  const blocked = status === 'blocked';

  return (
    <div
      className={`rounded-2xl border p-3 transition ${done
          ? 'border-green-500/30 bg-green-500/10'
          : active
            ? 'border-blue-500/40 bg-blue-500/10'
            : blocked
              ? 'border-white/5 bg-white/[0.015] opacity-60'
              : 'border-white/10 bg-white/[0.02]'
        }`}
    >
      <div className="flex gap-3">
        <div
          className={`rounded-xl p-2 ${done
              ? 'bg-green-500/10 text-green-300'
              : active
                ? 'bg-blue-500/10 text-blue-300'
                : 'bg-slate-900 text-slate-500'
            }`}
        >
          <Icon size={16} />
        </div>

        <div>
          <p className="text-sm font-semibold text-white">
            {title}
          </p>

          <p className="mt-1 text-xs leading-5 text-slate-500">
            {description}
          </p>
        </div>
      </div>
    </div>
  );
}

function SetupCompleteModal({
  routerId,
  hostname,
  wgIp,
  onClose,
}: {
  routerId: string;
  hostname: string;
  wgIp: string;
  onClose: () => void;
}) {
  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/75 p-4 backdrop-blur-sm">
      <div className="w-full max-w-xl rounded-3xl border border-green-500/30 bg-slate-950 p-6 shadow-2xl shadow-green-500/10">
        <div className="flex gap-4">
          <div className="rounded-2xl bg-green-500/10 p-3 text-green-300">
            <CheckCircle2 size={30} />
          </div>

          <div className="flex-1">
            <h2 className="text-2xl font-bold text-white">
              Configuração do router concluída
            </h2>

            <p className="mt-3 text-sm leading-6 text-slate-300">
              O provisionamento do router terminou com sucesso e o peer WireGuard da VPS foi registado.
            </p>

            <div className="mt-5 rounded-2xl border border-white/10 bg-white/[0.03] p-4 font-mono text-sm text-slate-300">
              <p>ROUTER_ID={routerId}</p>
              <p>HOSTNAME={hostname}</p>
              <p>WG_IP={wgIp}</p>
            </div>

            <div className="mt-6 flex justify-end">
              <Button type="button" onClick={onClose}>
                Concluir
              </Button>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}