import { useState } from "react";
import { ChevronDown } from "lucide-react";
import { invoke } from "@tauri-apps/api/core";
import type { RouterItem } from "../types/router";
import {
    AlertTriangle,
    CheckCircle2,
    Router,
    Search,
    ShieldCheck,
    XCircle,
} from "lucide-react";

type DetectionResult = {
    detected: boolean;
    ip: string | null;
    method: string;
    ssh_reachable: boolean;
    message: string;
};

type PrepareResult = {
    success: boolean;
    hostname_updated: boolean;
    password_updated: boolean;
    message: string;
    logs: string;
};

type CompatibilityResult = {
    compatible: boolean;
    version: string | null;
    target: string | null;
    arch: string | null;
    reason: string | null;
};

type ReadinessResult = {
    internet_ok: boolean;
    dns_ok: boolean;
    opkg_ok: boolean;
    openvpn_installed: boolean;
    free_space: string | null;
    free_memory: string | null;
};

type SshResult = {
    connected: boolean;
    host: string;
    hostname: string | null;
    openwrt_release: string | null;
    compatibility: CompatibilityResult | null;
    readiness: ReadinessResult | null;
    message: string;
};

type Props = {
    routers: RouterItem[];
};

export function OpenWrtConfigPage({ routers }: Props) {
    const [detecting, setDetecting] = useState(false);
    const [connecting, setConnecting] = useState(false);
    const [detection, setDetection] = useState<DetectionResult | null>(null);
    const [sshResult, setSshResult] = useState<SshResult | null>(null);

    const [host, setHost] = useState("");
    const [username, setUsername] = useState("root");
    const [password, setPassword] = useState("");
    const [selectedRouterId, setSelectedRouterId] = useState("");
    const [newRootPassword, setNewRootPassword] = useState("");
    const [confirmRootPassword, setConfirmRootPassword] = useState("");
    const [routerDropdownOpen, setRouterDropdownOpen] = useState(false);

    const [preparing, setPreparing] = useState(false);
    const [prepareResult, setPrepareResult] = useState<PrepareResult | null>(null);

    const compatibility = sshResult?.compatibility;

    async function detectRouter() {
        try {
            setDetecting(true);
            setSshResult(null);

            const result = await invoke<DetectionResult>("detect_openwrt_router");

            setDetection(result);

            if (result.ip) {
                setHost(result.ip);
            }
        } finally {
            setDetecting(false);
        }
    }

    const sshAuthFailed =
        sshResult &&
        !sshResult.connected &&
        sshResult.message.toLowerCase().includes("permission denied");

    async function prepareRouter() {
        if (!selectedRouter || !targetHostname) return;

        try {
            setPreparing(true);
            setPrepareResult(null);

            const result = await invoke<PrepareResult>("prepare_openwrt_router", {
                host,
                username,
                password,
                targetHostname,
                newPassword: newRootPassword,
            });

            setPrepareResult(result);

            if (result.success) {
                setPassword(newRootPassword);
                setNewRootPassword("");
                setConfirmRootPassword("");

                const refreshed = await invoke<SshResult>("test_openwrt_ssh", {
                    host,
                    username,
                    password: newRootPassword,
                });

                setSshResult(refreshed);
            }
        } finally {
            setPreparing(false);
        }
    }

    async function connectSsh() {
        try {
            setConnecting(true);

            const result = await invoke<SshResult>("test_openwrt_ssh", {
                host,
                username,
                password,
            });

            setSshResult(result);
        } finally {
            setConnecting(false);
        }
    }

    const selectedRouter = routers.find((router) => router.id === selectedRouterId);

    const vpnIpParts = selectedRouter?.vpnIp?.split(".") ?? [];

    const targetHostname = selectedRouter?.vpnIp
        ? `Litoral_Regas_${vpnIpParts[vpnIpParts.length - 1]}`
        : "";

    return (
        <section className="page-stack">
            <div className="page-header">
                <div>
                    <h1>Configuração OpenWRT</h1>
                    <p>Detetar router local, testar SSH e validar compatibilidade</p>
                </div>

                <button className="primary" onClick={detectRouter} disabled={detecting}>
                    <Search size={16} />
                    {detecting ? "A detetar..." : "Detetar Router"}
                </button>
            </div>

            <div className="openwrt-grid">
                <div className="dashboard-card">
                    <div className="card-header">
                        <div>
                            <h2>Deteção do Router</h2>
                            <p>Procura pelo gateway local ou pelo IP padrão OpenWRT</p>
                        </div>
                    </div>

                    <div className="status-note">
                        <Router size={24} />

                        <p>
                            {detection
                                ? detection.message
                                : "Ainda não foi executada nenhuma deteção."}
                        </p>
                    </div>

                    {detection?.ip && (
                        <div className="detail-list">
                            <DetailRow label="IP detetado" value={detection.ip} />
                            <DetailRow label="Método" value={detection.method} />
                            <DetailRow
                                label="SSH"
                                value={detection.ssh_reachable ? "Disponível" : "Indisponível"}
                            />
                        </div>
                    )}
                </div>

                <div className="dashboard-card">
                    <div className="card-header">
                        <div>
                            <h2>Ligação SSH</h2>
                            <p>Introduza as credenciais do router OpenWRT</p>
                        </div>
                    </div>

                    <div className="openwrt-form">
                        <label>
                            IP do Router
                            <input value={host} onChange={(e) => setHost(e.target.value)} />
                        </label>

                        <label>
                            Utilizador
                            <input
                                value={username}
                                onChange={(e) => setUsername(e.target.value)}
                            />
                        </label>

                        <label>
                            Password
                            <input
                                type="password"
                                value={password}
                                onChange={(e) => {
                                    setPassword(e.target.value);

                                    if (sshResult && !sshResult.connected) {
                                        setSshResult(null);
                                    }
                                }}
                                placeholder="Password SSH"
                            />
                            {sshAuthFailed && (
                                <span className="form-error">
                                    Password SSH inválida ou em falta. Introduza uma password válida.
                                </span>
                            )}
                        </label>
                        <div className="openwrt-button-wrap">
                            <button
                                className="primary"
                                onClick={connectSsh}
                                disabled={connecting || !host || !username}
                            >
                                <ShieldCheck size={16} />
                                {connecting ? "A ligar..." : "Ligar ao Router"}
                            </button>
                        </div>
                    </div>
                </div>

                {sshResult && (
                    <div className="dashboard-card wide-panel">
                        <div className="card-header">
                            <div>
                                <h2>Resultado da Ligação</h2>
                                <p>Estado da sessão SSH com o router</p>
                            </div>
                        </div>

                        <div className="detail-list">
                            <DetailRow
                                label="Estado"
                                value={sshResult.connected ? "Ligado" : "Falhou"}
                            />

                            <DetailRow label="Host" value={sshResult.host} />
                            <DetailRow label="Hostname" value={sshResult.hostname || "-"} />
                        </div>

                        {!sshResult.connected && (
                            <div className="status-note">
                                <XCircle size={24} />
                                <p>
                                    {sshAuthFailed
                                        ? "Não foi possível autenticar. Verifique a password SSH."
                                        : sshResult.message}
                                </p>
                            </div>
                        )}
                    </div>
                )}

                {sshResult?.connected && compatibility && (
                    <div className="dashboard-card wide-panel">
                        <div className="card-header">
                            <div>
                                <h2>Compatibilidade OpenWRT</h2>
                                <p>Validação da versão e arquitetura do firmware</p>
                            </div>

                            <span
                                className={`badge ${compatibility.compatible ? "success" : "failed"
                                    }`}
                            >
                                {compatibility.compatible ? "Compatível" : "Não compatível"}
                            </span>
                        </div>

                        <div
                            className={`status-note ${compatibility.compatible ? "compatible" : "unsupported"
                                }`}
                        >
                            {compatibility.compatible ? (
                                <CheckCircle2 size={24} />
                            ) : (
                                <AlertTriangle size={24} />
                            )}

                            <p>
                                {compatibility.compatible
                                    ? "Este router cumpre os requisitos mínimos para configuração OpenVPN."
                                    : compatibility.reason ||
                                    "Este router não cumpre os requisitos mínimos."}
                            </p>
                        </div>

                        <div className="detail-list">
                            <DetailRow
                                label="Versão OpenWRT"
                                value={compatibility.version || "-"}
                            />

                            <DetailRow
                                label="Target"
                                value={compatibility.target || "-"}
                            />

                            <DetailRow
                                label="Arquitetura"
                                value={compatibility.arch || "-"}
                            />

                            <DetailRow
                                label="Versão mínima"
                                value="21.02.2"
                            />
                        </div>

                        {sshResult.openwrt_release && (
                            <div className="log-box">
                                <pre>{sshResult.openwrt_release}</pre>
                            </div>
                        )}
                    </div>
                )}

                {sshResult?.connected && sshResult.readiness && (
                    <div className="dashboard-card wide-panel">
                        <div className="card-header">
                            <div>
                                <h2>Estado do Router</h2>
                                <p>Verificações antes da configuração OpenVPN</p>
                            </div>
                        </div>

                        <div className="detail-list">
                            <DetailRow
                                label="Internet"
                                value={sshResult.readiness.internet_ok ? "Disponível" : "Indisponível"}
                            />

                            <DetailRow
                                label="DNS"
                                value={sshResult.readiness.dns_ok ? "Disponível" : "Indisponível"}
                            />

                            <DetailRow
                                label="OPKG"
                                value={sshResult.readiness.opkg_ok ? "Disponível" : "Indisponível"}
                            />

                            <DetailRow
                                label="OpenVPN"
                                value={sshResult.readiness.openvpn_installed ? "Instalado" : "Não instalado"}
                            />

                            <DetailRow
                                label="Espaço livre"
                                value={sshResult.readiness.free_space || "-"}
                            />

                            <DetailRow
                                label="Memória livre"
                                value={sshResult.readiness.free_memory || "-"}
                            />
                        </div>
                    </div>
                )}

                {sshResult?.connected && sshResult.readiness && (
                    <div className="dashboard-card wide-panel">
                        <div className="card-header">
                            <div>
                                <h2>Preparação do Router</h2>
                                <p>Associe este router físico a um router da plataforma</p>
                            </div>
                        </div>

                        <div className="openwrt-prepare-form">
                            <label>
                                Router da Plataforma
                                <div className="custom-select">
                                    <button
                                        type="button"
                                        className="custom-select-button"
                                        onClick={() => setRouterDropdownOpen((prev) => !prev)}
                                    >
                                        <span>
                                            {selectedRouter
                                                ? `${selectedRouter.name} - ${selectedRouter.vpnIp}`
                                                : "Selecionar router..."}
                                        </span>

                                        <ChevronDown
                                            size={16}
                                            className={`chevron ${routerDropdownOpen ? "open" : ""}`}
                                        />
                                    </button>

                                    {routerDropdownOpen && (
                                        <div className="custom-select-menu">
                                            {routers.map((router) => (
                                                <button
                                                    key={router.id}
                                                    type="button"
                                                    className="custom-select-option"
                                                    onClick={() => {
                                                        setSelectedRouterId(router.id);
                                                        setRouterDropdownOpen(false);
                                                    }}
                                                >
                                                    {router.name} - {router.vpnIp}
                                                </button>
                                            ))}
                                        </div>
                                    )}
                                </div>
                            </label>

                            <label>
                                Hostname Gerado
                                <input value={targetHostname || "-"} readOnly />
                            </label>

                            <label>
                                Nova Password Root
                                <input
                                    type="password"
                                    value={newRootPassword}
                                    onChange={(e) => setNewRootPassword(e.target.value)}
                                    placeholder="Nova password"
                                />
                            </label>

                            <label>
                                Confirmar Password Root
                                <input
                                    type="password"
                                    value={confirmRootPassword}
                                    onChange={(e) => setConfirmRootPassword(e.target.value)}
                                    placeholder="Confirmar password"
                                />

                                {confirmRootPassword &&
                                    newRootPassword !== confirmRootPassword && (
                                        <span className="form-error">
                                            As passwords não coincidem.
                                        </span>
                                    )}
                            </label>
                        </div>

                        {selectedRouter && (
                            <div className="detail-list">
                                <DetailRow label="Router selecionado" value={selectedRouter.name} />
                                <DetailRow label="IP VPN" value={selectedRouter.vpnIp || "-"} />
                                <DetailRow label="Hostname final" value={targetHostname} />
                            </div>
                        )}

                        <div className="modal-actions">
                            <button
                                className="primary"
                                onClick={prepareRouter}
                                disabled={
                                    preparing ||
                                    !selectedRouter ||
                                    !targetHostname ||
                                    !newRootPassword ||
                                    newRootPassword !== confirmRootPassword
                                }
                            >
                                {preparing ? "A preparar..." : "Preparar Router"}
                            </button>
                        </div>
                    </div>
                )}

                {prepareResult && (
                    <div className="dashboard-card wide-panel">
                        <div className="card-header">
                            <div>
                                <h2>Resultado da Preparação</h2>
                                <p>Estado da configuração inicial do router</p>
                            </div>

                            <span className={`badge ${prepareResult.success ? "success" : "failed"}`}>
                                {prepareResult.success ? "Sucesso" : "Falhou"}
                            </span>
                        </div>

                        <div className="detail-list">
                            <DetailRow
                                label="Hostname"
                                value={prepareResult.hostname_updated ? "Atualizado" : "Falhou"}
                            />

                            <DetailRow
                                label="Password Root"
                                value={prepareResult.password_updated ? "Atualizada" : "Falhou"}
                            />
                        </div>

                        <div className="status-note">
                            {prepareResult.success ? <CheckCircle2 size={24} /> : <XCircle size={24} />}
                            <p>{prepareResult.message}</p>
                        </div>

                        {prepareResult.logs && (
                            <div className="log-box">
                                <pre>{prepareResult.logs}</pre>
                            </div>
                        )}
                    </div>
                )}
            </div>
        </section>

    );
}

function DetailRow({ label, value }: { label: string; value: string }) {
    return (
        <div className="detail-row">
            <span>{label}</span>
            <strong>{value}</strong>
        </div>
    );
}