import { Head, useForm } from '@inertiajs/react';
import {
    AlertTriangle,
    Archive,
    CheckCircle2,
    LoaderCircle,
    UploadCloud,
} from 'lucide-react';
import { useRef, useState } from 'react';
import {
    PageHeader,
    Panel,
    Stat,
    shortDate,
} from '@/components/admin/primitives';

interface SystemUpdateProps {
    system: {
        version: string;
        php: string;
        laravel: string;
        database: string;
        environment: string;
        debug: boolean;
        installedAt: string | null;
        maxUpload: string;
    };
    backups: Array<{ name: string; size: number; at: string }>;
}

const megabytes = (bytes: number): string =>
    `${(bytes / 1024 / 1024).toFixed(1)} MB`;

export default function SystemUpdate({ system, backups }: SystemUpdateProps) {
    const inputRef = useRef<HTMLInputElement>(null);
    const [name, setName] = useState<string | null>(null);
    const form = useForm<{ package: File | null }>({ package: null });

    return (
        <>
            <Head title="Actualización del sistema" />

            <div className="space-y-6 p-5">
                <PageHeader
                    eyebrow="Mantenimiento"
                    title="Actualización"
                    description="Sube el paquete ZIP de una versión nueva. Se respalda el código actual, se reemplazan los archivos, se aplican las migraciones y se limpian las cachés."
                />

                <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
                    <Stat
                        value={system.version}
                        label="Versión instalada"
                        hint={
                            system.installedAt
                                ? `desde ${shortDate(system.installedAt)}`
                                : undefined
                        }
                        tone="accent"
                    />
                    <Stat value={system.php} label="PHP" />
                    <Stat value={system.laravel} label="Laravel" />
                    <Stat
                        value={system.database}
                        label="Base de datos"
                        hint={system.environment}
                    />
                </div>

                {system.debug ? (
                    <p className="flex items-start gap-2 rounded-xl border border-status-held/40 bg-status-held-soft px-3 py-2.5 text-[13px] leading-5 text-status-held">
                        <AlertTriangle className="mt-px size-4 shrink-0" />
                        <span>
                            <strong>APP_DEBUG está encendido.</strong> En un
                            sitio público muestra rutas y credenciales cuando
                            algo falla. Ponlo en <code>false</code> dentro de{' '}
                            <code>.env</code>.
                        </span>
                    </p>
                ) : null}

                <div className="grid gap-4 lg:grid-cols-[1.2fr_0.8fr]">
                    <Panel title="Instalar una actualización">
                        <form
                            onSubmit={(event) => {
                                event.preventDefault();
                                form.post('/admin/actualizacion', {
                                    forceFormData: true,
                                    preserveScroll: true,
                                    onSuccess: () => {
                                        setName(null);
                                        form.reset();

                                        if (inputRef.current) {
                                            inputRef.current.value = '';
                                        }
                                    },
                                });
                            }}
                            className="space-y-3 p-4"
                        >
                            <input
                                ref={inputRef}
                                type="file"
                                accept=".zip,application/zip"
                                className="hidden"
                                onChange={(event) => {
                                    const file =
                                        event.target.files?.[0] ?? null;
                                    setName(file?.name ?? null);
                                    form.setData('package', file);
                                }}
                            />

                            <button
                                type="button"
                                onClick={() => inputRef.current?.click()}
                                className="flex w-full flex-col items-center gap-2 rounded-2xl border border-dashed border-border px-4 py-9 text-center hover:bg-muted"
                            >
                                <UploadCloud className="size-6 text-muted-foreground" />
                                <span className="text-[13px] font-bold text-foreground">
                                    {name ?? 'Selecciona el ZIP de la versión'}
                                </span>
                                <span className="text-[12px] text-muted-foreground">
                                    Máximo {system.maxUpload} por la
                                    configuración de PHP
                                </span>
                            </button>

                            {form.errors.package ? (
                                <p className="text-[13px] text-destructive">
                                    {form.errors.package}
                                </p>
                            ) : null}

                            {form.progress ? (
                                <div className="h-1.5 overflow-hidden rounded-full bg-muted">
                                    <span
                                        className="block h-full rounded-full bg-brand transition-[width]"
                                        style={{
                                            width: `${form.progress.percentage ?? 0}%`,
                                        }}
                                    />
                                </div>
                            ) : null}

                            <button
                                type="submit"
                                disabled={form.processing || name === null}
                                className="flex w-full items-center justify-center gap-2 rounded-xl bg-brand px-4 py-3 text-[13px] font-bold text-brand-foreground hover:bg-brand/90 disabled:bg-muted-foreground/40"
                            >
                                {form.processing ? (
                                    <LoaderCircle className="size-4.5 animate-spin" />
                                ) : (
                                    <CheckCircle2 className="size-4.5" />
                                )}
                                {form.processing
                                    ? 'Aplicando la actualización…'
                                    : 'Aplicar actualización'}
                            </button>

                            <p className="text-[12px] leading-4 text-muted-foreground">
                                No se tocan tu archivo <code>.env</code>, los
                                planos ni la galería. El paquete sólo reemplaza
                                el código de la aplicación y debe declarar su
                                versión en <code>install/release.json</code>.
                            </p>
                        </form>
                    </Panel>

                    <Panel
                        title="Respaldos"
                        action={
                            <span className="text-[12px] text-muted-foreground">
                                {backups.length}
                            </span>
                        }
                    >
                        {backups.length === 0 ? (
                            <p className="px-4 py-8 text-center text-[13px] text-muted-foreground">
                                Aquí quedará una copia del código cada vez que
                                apliques una actualización.
                            </p>
                        ) : (
                            <ul className="divide-y divide-border">
                                {backups.map((backup) => (
                                    <li
                                        key={backup.name}
                                        className="flex items-center justify-between gap-3 px-4 py-2.5"
                                    >
                                        <span className="flex min-w-0 items-center gap-2">
                                            <Archive className="size-4 shrink-0 text-muted-foreground" />
                                            <span className="min-w-0">
                                                <span className="block truncate text-[13px] font-semibold text-foreground">
                                                    {backup.name}
                                                </span>
                                                <span className="block text-[12px] text-muted-foreground">
                                                    {shortDate(backup.at)}
                                                </span>
                                            </span>
                                        </span>
                                        <span className="shrink-0 text-[12px] text-muted-foreground">
                                            {megabytes(backup.size)}
                                        </span>
                                    </li>
                                ))}
                            </ul>
                        )}
                        <p className="border-t border-border px-4 py-3 text-[12px] leading-4 text-muted-foreground">
                            Los respaldos viven en{' '}
                            <code>storage/app/backups</code>. Bórralos por FTP
                            cuando ya no los necesites.
                        </p>
                    </Panel>
                </div>
            </div>
        </>
    );
}
