import { useMemo, useState } from 'react';
import { invoke } from '@tauri-apps/api/core';
import {
  Activity,
  CheckCircle2,
  Cpu,
  Eye,
  EyeOff,
  Network,
  Play,
  RadioTower,
  Search,
  Terminal,
  UploadCloud,
} from 'lucide-react';

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

type Udp2rawStep = {
  id: string;
  title: string;
  description: string;
  command: string;
  logLabel: string;
  icon: typeof Search;
};

const steps: Udp2rawStep[] = [
  {
    id: 'status',
    title: 'Verificar Estado',
    description: 'Confirma binário, serviço, processo e porta local.',
    command: 'check_udp2raw_router_status',
    logLabel: 'A verificar estado UDP2RAW no router...',
    icon: Search,
  },
  {
    id: 'binary',
    title: 'Enviar Binário',
    description: 'Copia o binário udp2raw para /usr/bin/udp2raw.',
    command: 'upload_udp2raw_binary',
    logLabel: 'A enviar binário UDP2RAW para o router...',
    icon: Cpu,
  },
  {
    id: 'script',
    title: 'Enviar Script',
    description: 'Copia o script de instalação para /tmp.',
    command: 'upload_udp2raw_setup_script',
    logLabel: 'A enviar script UDP2RAW para o router...',
    icon: UploadCloud,
  },
  {
    id: 'setup',
    title: 'Executar Setup',
    description: 'Cria o serviço init.d e arranca o túnel.',
    command: 'run_udp2raw_setup',
    logLabel: 'A executar configuração UDP2RAW...',
    icon: Play,
  },
  {
    id: 'test',
    title: 'Testar Túnel',
    description: 'Valida processo, listener, ping e estado WireGuard.',
    command: 'test_udp2raw_tunnel',
    logLabel: 'A testar túnel UDP2RAW...',
    icon: CheckCircle2,
  },
];

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';

export function Udp2rawConfig() {
  const [routerIp, setRouterIp] = useState('198.51.100.1');
  const [password, setPassword] = useState('litoralr');
  const [runningStep, setRunningStep] = useState<string | null>(null);
  const [completedSteps, setCompletedSteps] = useState<string[]>([]);
  const [failedStep, setFailedStep] = useState<string | null>(null);
  const [log, setLog] = useState<string[]>([]);
  const [showPassword, setShowPassword] = useState(false);

  const running = Boolean(runningStep);

  const statusTone = useMemo(() => {
    if (failedStep) return 'red';
    if (completedSteps.includes('test')) return 'green';
    if (running) return 'purple';
    return 'blue';
  }, [completedSteps, failedStep, running]);

  const statusLabel = useMemo(() => {
    if (failedStep) return 'erro';
    if (completedSteps.includes('test')) return 'validado';
    if (running) return 'a executar';
    return 'pronto';
  }, [completedSteps, failedStep, running]);

  const progress =
    (completedSteps.length / steps.length) * 100;

  function addLog(message: string) {
    setLog((current) => [
      `${new Date().toLocaleTimeString()}  ${message}`,
      ...current,
    ]);
  }

  async function runStep(step: Udp2rawStep) {
    if (running) {
      return;
    }

    setRunningStep(step.id);
    setFailedStep(null);

    try {
      addLog(step.logLabel);

      const result = await invoke<string>(step.command, {
        ip: routerIp,
        password,
      });

      addLog(result || 'Concluído.');

      setCompletedSteps((current) => [
        ...new Set([
          ...current,
          step.id,
        ]),
      ]);
    } catch (error) {
      setFailedStep(step.id);
      addLog(`ERRO: ${String(error)}`);
    } finally {
      setRunningStep(null);
    }
  }

  async function runFullFlow() {
    if (running) {
      return;
    }

    setFailedStep(null);

    for (const step of steps) {
      await runStep(step);

      if (failedStep) {
        return;
      }
    }
  }

  function clearLog() {
    setLog([]);
    setCompletedSteps([]);
    setFailedStep(null);
  }

  return (
    <div className="flex min-h-full flex-col">
      <div className="mb-5 flex items-start justify-between gap-4 rounded-3xl border border-white/10 bg-white/[0.025] px-5 py-4">
        <div className="flex min-w-0 items-center gap-4">
          <div className="relative shrink-0">
            <div className="absolute inset-0 rounded-3xl bg-blue-500/20 blur-xl" />

            <div className="relative rounded-3xl border border-blue-400/20 bg-blue-500/10 p-4 text-blue-300">
              <RadioTower size={28} />
            </div>
          </div>

          <div className="min-w-0">
            <h1 className="truncate text-3xl font-black tracking-tight text-white">
              Configuração UDP2RAW
            </h1>

            <p className="mt-1 text-sm text-slate-400">
              Instalação, arranque e validação do túnel UDP2RAW no router.
            </p>
          </div>
        </div>

        <Badge tone={statusTone}>
          {statusLabel}
        </Badge>
      </div>

      <div className="grid gap-4 xl:grid-cols-12">
        <Card className="relative overflow-hidden xl:col-span-5">
          <div className="pointer-events-none absolute inset-x-0 top-0 h-px bg-gradient-to-r from-transparent via-blue-400/30 to-transparent" />

          <div className="mb-5 flex items-center gap-4">
            <div className="rounded-2xl border border-blue-400/10 bg-blue-500/10 p-3 text-blue-300">
              <Network size={24} />
            </div>

            <div className="min-w-0">
              <h2 className="text-xl font-bold text-white">
                Router Alvo
              </h2>

              <p className="text-sm text-slate-400">
                Defina o router onde o cliente UDP2RAW será configurado.
              </p>
            </div>
          </div>

          <div className="grid gap-4 lg:grid-cols-2 xl:grid-cols-1">
            <div>
              <label className="mb-2 block text-xs font-bold uppercase tracking-[0.16em] text-slate-500">
                IP do Router
              </label>

              <input
                value={routerIp}
                disabled={running}
                onChange={(event) =>
                  setRouterIp(event.target.value)
                }
                className="w-full rounded-2xl border border-white/10 bg-black/20 px-4 py-3 font-mono text-sm text-white outline-none transition placeholder:text-slate-600 focus:border-blue-500/50 focus:bg-black/30 focus:shadow-[0_0_0_4px_rgba(59,130,246,0.10)] disabled:cursor-not-allowed disabled:opacity-60"
              />
            </div>

            <div>
              <label className="mb-2 block text-xs font-bold uppercase tracking-[0.16em] text-slate-500">
                Palavra-passe SSH
              </label>

              <div className="relative">
                <input
                  type={showPassword ? 'text' : 'password'}
                  value={password}
                  disabled={running}
                  onChange={(event) =>
                    setPassword(event.target.value)
                  }
                  placeholder="Vazio se não existir"
                  className="w-full rounded-2xl border border-white/10 bg-black/20 px-4 py-3 pr-14 font-mono text-sm text-white outline-none transition placeholder:text-slate-600 focus:border-blue-500/50 focus:bg-black/30 focus:shadow-[0_0_0_4px_rgba(59,130,246,0.10)] disabled:cursor-not-allowed disabled:opacity-60"
                />

                <button
                  type="button"
                  onClick={() =>
                    setShowPassword((current) => !current)
                  }
                  className="absolute right-3 top-1/2 flex h-8 w-8 -translate-y-1/2 items-center justify-center rounded-xl text-slate-500 transition hover:bg-white/5 hover:text-blue-300"
                >
                  {showPassword ? (
                    <EyeOff size={18} />
                  ) : (
                    <Eye size={18} />
                  )}
                </button>
              </div>
            </div>
          </div>

          <div className="mt-5 grid grid-cols-2 gap-3">
            {[
              ['VPS', '146.59.230.190:444'],
              ['Local', '127.0.0.1:4999'],
              ['Modo', 'faketcp'],
              ['Serviço', 'udp2raw-wg'],
            ].map(([label, value]) => (
              <div
                key={label}
                className="rounded-2xl border border-white/10 bg-white/[0.025] p-4"
              >
                <p className="text-[10px] font-bold uppercase tracking-[0.16em] text-slate-500">
                  {label}
                </p>

                <p className="mt-2 break-all font-mono text-xs font-semibold text-slate-200">
                  {value}
                </p>
              </div>
            ))}
          </div>
        </Card>

        <Card className="overflow-hidden xl:col-span-7">
          <div className="mb-4 flex flex-wrap items-start justify-between gap-4">
            <div>
              <h2 className="text-lg font-bold text-white">
                Fluxo de Instalação
              </h2>

              <p className="mt-1 text-sm text-slate-400">
                Execute passo a passo ou corra o fluxo completo.
              </p>
            </div>

            <button
              type="button"
              disabled={running}
              onClick={runFullFlow}
              className="inline-flex shrink-0 items-center gap-2 rounded-2xl border border-blue-400/20 bg-blue-500/15 px-4 py-3 text-sm font-bold text-blue-100 shadow-lg shadow-blue-500/10 transition hover:-translate-y-[1px] hover:bg-blue-500/25 disabled:cursor-not-allowed disabled:opacity-60"
            >
              <Activity size={16} />
              Executar Tudo
            </button>
          </div>

          <div className="mb-4">
            <div className="mb-2 flex justify-between text-xs text-slate-500">
              <span>Progresso</span>
              <span>{completedSteps.length}/{steps.length}</span>
            </div>

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

          <div className="grid gap-3 md:grid-cols-2">
            {steps.map((step, index) => {
              const done = completedSteps.includes(step.id);
              const active = runningStep === step.id;
              const failed = failedStep === step.id;
              const Icon = step.icon;

              return (
                <button
                  key={step.id}
                  type="button"
                  disabled={running}
                  onClick={() => runStep(step)}
                  className={`group rounded-2xl border p-4 text-left transition disabled:cursor-not-allowed ${
                    failed
                      ? 'border-red-500/30 bg-red-500/10'
                      : done
                        ? 'border-green-500/30 bg-green-500/10'
                        : active
                          ? 'border-blue-500/40 bg-blue-500/10 shadow-lg shadow-blue-500/10'
                          : 'border-white/10 bg-white/[0.02] hover:border-blue-500/25 hover:bg-white/[0.04]'
                  }`}
                >
                  <div className="flex items-start gap-3">
                    <div
                      className={`flex h-10 w-10 shrink-0 items-center justify-center rounded-2xl ${
                        failed
                          ? 'bg-red-500/10 text-red-300'
                          : done
                            ? 'bg-green-500/10 text-green-300'
                            : active
                              ? 'bg-blue-500/10 text-blue-300'
                              : 'bg-slate-900 text-slate-500 group-hover:text-blue-300'
                      }`}
                    >
                      <Icon size={17} />
                    </div>

                    <div className="min-w-0 flex-1">
                      <div className="flex items-center justify-between gap-3">
                        <p className="truncate text-sm font-bold text-white">
                          {step.title}
                        </p>

                        <span className="font-mono text-[10px] text-slate-600">
                          {String(index + 1).padStart(2, '0')}
                        </span>
                      </div>

                      <p className="mt-1 line-clamp-2 text-xs leading-5 text-slate-500">
                        {step.description}
                      </p>
                    </div>
                  </div>
                </button>
              );
            })}
          </div>
        </Card>
      </div>

      <Card className="mt-4 flex min-h-[240px] flex-col overflow-hidden">
        <div className="mb-4 flex items-center justify-between gap-3">
          <div className="flex items-center gap-3">
            <div className="rounded-2xl border border-blue-400/10 bg-blue-500/10 p-3 text-blue-300">
              <Terminal size={22} />
            </div>

            <div>
              <h2 className="text-lg font-bold text-white">
                Log UDP2RAW
              </h2>

              <p className="text-sm text-slate-400">
                Saída dos comandos executados no router.
              </p>
            </div>
          </div>

          <button
            type="button"
            disabled={running}
            onClick={clearLog}
            className="rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-2 text-sm font-bold text-slate-300 transition hover:border-blue-500/30 hover:bg-blue-500/10 hover:text-blue-100 disabled:cursor-not-allowed disabled:opacity-60"
          >
            Limpar
          </button>
        </div>

        <pre
          className={`max-h-[280px] min-h-[150px] overflow-auto whitespace-pre-wrap break-words rounded-3xl border border-white/10 bg-black/25 p-5 font-mono text-xs leading-6 text-slate-300 ${scrollClass}`}
        >
          {log.join('\n\n') || 'Ainda não há atividade UDP2RAW.'}
        </pre>
      </Card>
    </div>
  );
}