import { useMemo, useRef } from 'react';
import { Transition } from '@headlessui/react';
import { Head, Form, Link, router, useForm, usePage } from '@inertiajs/react';
import { useTranslation } from 'react-i18next';
import { CalendarClock, CheckCircle2, MailWarning, ReceiptText } from 'lucide-react';

import ProfileController from '@/actions/App/Http/Controllers/Settings/ProfileController';
import PasswordController from '@/actions/App/Http/Controllers/Settings/PasswordController';
import InputError from '@/components/input-error';
import AppLayout from '@/layouts/app-layout';
import { type BreadcrumbItem, type SharedData } from '@/types';

import { Button } from '@/components/ui/button';
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Badge } from '@/components/ui/badge';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import { Separator } from '@/components/ui/separator';
import { send as resendVerificationRoute } from '@/routes/verification';

type ProfilePageProps = {
    userData: {
        id: number;
        name: string;
        email: string;
        username?: string | null;
        preferredLocale?: string | null;
        emailVerifiedAt: string | null;
        mustVerifyEmail: boolean;
    };
    tenant: {
        id: number;
        name: string;
        subscriptionStatus: string | null;
        subscriptionExpiresAt: string | null;
        activePackage: {
            name: string;
            price: number | null;
            expiresAt: string | null;
            remainingEvents: number | null;
        } | null;
    } | null;
    purchases: Array<{
        id: number;
        packageName: string;
        price: number | null;
        purchasedAt: string | null;
        type: string | null;
        provider: string | null;
    }>;
    dataExport: {
        exports: Array<{
            id: number;
            status: string;
            size: number | null;
            created_at: string | null;
            expires_at: string | null;
            download_url: string | null;
            error_message: string | null;
        }>;
        hasPending: boolean;
        nextRequestAt?: string | null;
    };
};

const breadcrumbs: BreadcrumbItem[] = [
    {
        title: 'Profil',
        href: '/profile',
    },
];

export default function ProfileIndex() {
    const { userData, tenant, purchases, supportedLocales, locale, dataExport } = usePage<SharedData & ProfilePageProps>().props;
    const { t } = useTranslation('profile');

    const dateFormatter = useMemo(() => new Intl.DateTimeFormat(locale ?? 'de-DE', {
        day: '2-digit',
        month: 'long',
        year: 'numeric',
    }), [locale]);

    const currencyFormatter = useMemo(() => new Intl.NumberFormat(locale ?? 'de-DE', {
        style: 'currency',
        currency: 'EUR',
        maximumFractionDigits: 2,
    }), [locale]);

    const byteFormatter = useMemo(() => new Intl.NumberFormat(locale ?? 'de-DE', {
        maximumFractionDigits: 1,
    }), [locale]);

    const dataExportInfo = dataExport ?? { exports: [], hasPending: false, nextRequestAt: null };
    const nextRequestDeadline = dataExportInfo.nextRequestAt ? new Date(dataExportInfo.nextRequestAt) : null;
    const canRequestExport = !dataExportInfo.hasPending && (!nextRequestDeadline || nextRequestDeadline <= new Date());

    const handleExportRequest = () => {
        router.post('/profile/data-exports');
    };

    const deleteForm = useForm({ confirmation: '' });

    const handleDeleteSubmit = (event: React.FormEvent) => {
        event.preventDefault();
        deleteForm.delete('/profile/account');
    };

    const formatExportStatus = (status: string) => t(`export.status.${status}`, status);

    const formatBytes = (input: number | null) => {
        if (!input) {
            return '—';
        }

        const units = ['B', 'KB', 'MB', 'GB'];
        let value = input;
        let unitIndex = 0;

        while (value >= 1024 && unitIndex < units.length - 1) {
            value /= 1024;
            unitIndex += 1;
        }

        return `${byteFormatter.format(value)} ${units[unitIndex]}`;
    };

    const registrationDate = useMemo(() => {
        if (!userData.emailVerifiedAt) {
            return null;
        }

        try {
            return dateFormatter.format(new Date(userData.emailVerifiedAt));
        } catch {
            return null;
        }
    }, [userData.emailVerifiedAt, dateFormatter]);

    const formatDate = (value: string | null) => (value ? dateFormatter.format(new Date(value)) : '—');
    const formatPrice = (price: number | null) => (price === null ? '—' : currencyFormatter.format(price));

    const localeOptions = (supportedLocales ?? ['de', 'en']).map((value) => ({
        label: value.toUpperCase(),
        value,
    }));

    return (
        <AppLayout breadcrumbs={breadcrumbs}>
            <Head title="Profil" />

            <div className="flex flex-1 flex-col gap-6 pb-12 pt-24 lg:pt-28">
                <Card className="border-border/60 bg-gradient-to-br from-background to-muted/50 shadow-sm">
                    <CardHeader className="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
                        <div>
                            <CardTitle className="text-2xl font-semibold">Hallo, {userData.name || userData.email}</CardTitle>
                            <p className="text-sm text-muted-foreground">
                                Hier verwaltest du deine Zugangsdaten, sprichst mit uns in deiner Lieblingssprache und behältst alle Buchungen im Blick.
                            </p>
                        </div>
                        <div className="flex flex-col items-start gap-2 sm:items-end">
                            <Badge variant={userData.emailVerifiedAt ? 'secondary' : 'outline'} className="flex items-center gap-2">
                                {userData.emailVerifiedAt ? <CheckCircle2 className="size-4 text-emerald-500" /> : <MailWarning className="size-4 text-amber-500" />}
                                {userData.emailVerifiedAt ? 'E-Mail bestätigt' : 'Bestätigung ausstehend'}
                            </Badge>
                            {registrationDate && (
                                <p className="text-xs text-muted-foreground">Aktiv seit {registrationDate}</p>
                            )}
                        </div>
                    </CardHeader>
                    {!userData.emailVerifiedAt && userData.mustVerifyEmail && (
                        <CardContent>
                            <Alert variant="warning" className="border-amber-300 bg-amber-100/80 text-amber-900 dark:border-amber-700 dark:bg-amber-900/20 dark:text-amber-50">
                                <MailWarning className="size-5" />
                                <div>
                                    <AlertTitle>E-Mail-Bestätigung ausstehend</AlertTitle>
                                    <AlertDescription>
                                        Bestätige deine E-Mail-Adresse, damit wir dich über Uploads, Rechnungen und Event-Updates informieren können.
                                        <div className="mt-3">
                                            <Link href={resendVerificationRoute()} as="button" method="post" className="text-sm font-medium underline underline-offset-4">
                                                Bestätigungslink erneut senden
                                            </Link>
                                        </div>
                                    </AlertDescription>
                                </div>
                            </Alert>
                        </CardContent>
                    )}
                </Card>

                <div className="grid gap-4 xl:grid-cols-3">
                    <Card className="xl:col-span-2">
                        <AccountForm userData={userData} localeOptions={localeOptions} />
                    </Card>
                    <Card>
                        <PasswordForm />
                    </Card>
                </div>

                <Card>
                    <CardHeader className="flex flex-col gap-2 md:flex-row md:items-center md:justify-between">
                        <div>
                            <CardTitle>Abonnements &amp; Pakete</CardTitle>
                            <p className="text-sm text-muted-foreground">
                                Hier findest du die wichtigsten Daten zu deinem aktuellen Paket und deinen letzten Buchungen.
                            </p>
                        </div>
                        {tenant?.activePackage ? (
                            <Badge variant="outline" className="flex items-center gap-2">
                                <CalendarClock className="size-4" /> Läuft bis {formatDate(tenant.activePackage.expiresAt)}
                            </Badge>
                        ) : (
                            <Badge variant="outline">Kein aktives Paket</Badge>
                        )}
                    </CardHeader>
                    <CardContent className="space-y-4">
                        {tenant?.activePackage ? (
                            <div className="grid gap-3 rounded-lg border border-dashed border-muted-foreground/30 bg-muted/30 p-4 md:grid-cols-2">
                                <div>
                                    <h3 className="text-base font-medium leading-tight">{tenant.activePackage.name}</h3>
                                    <p className="text-xs text-muted-foreground">{tenant.activePackage.remainingEvents ?? 0} Events inklusive</p>
                                </div>
                                <div className="grid gap-2 text-sm text-muted-foreground">
                                    <div className="flex items-center justify-between">
                                        <span>Status</span>
                                        <span className="font-medium capitalize">{tenant.subscriptionStatus ?? 'aktiv'}</span>
                                    </div>
                                    <div className="flex items-center justify-between">
                                        <span>Verlängerung</span>
                                        <span>{formatDate(tenant.subscriptionExpiresAt)}</span>
                                    </div>
                                    <div className="flex items-center justify-between">
                                        <span>Preis</span>
                                        <span>{formatPrice(tenant.activePackage.price)}</span>
                                    </div>
                                </div>
                            </div>
                        ) : (
                            <Alert className="border border-dashed border-muted-foreground/40 bg-muted/20">
                                <AlertDescription className="text-sm text-muted-foreground">
                                    Du hast aktuell kein aktives Paket. Wähle ein Paket, um ohne Unterbrechung neue Events zu planen.
                                </AlertDescription>
                            </Alert>
                        )}

                        <Separator />

                        <div className="space-y-2">
                            <div className="flex items-center gap-2 text-sm font-medium text-muted-foreground">
                                <ReceiptText className="size-4" /> Letzte Buchungen
                            </div>
                            {purchases.length === 0 ? (
                                <div className="rounded-md border border-dashed border-muted-foreground/30 p-6 text-sm text-muted-foreground text-center">
                                    Noch keine Buchungen vorhanden. Schaue im Dashboard vorbei, um passende Pakete zu finden.
                                </div>
                            ) : (
                                <Table>
                                    <TableHeader>
                                        <TableRow>
                                            <TableHead>Paket</TableHead>
                                            <TableHead className="hidden sm:table-cell">Typ</TableHead>
                                            <TableHead className="hidden md:table-cell">Anbieter</TableHead>
                                            <TableHead className="hidden md:table-cell">Datum</TableHead>
                                            <TableHead className="text-right">Preis</TableHead>
                                        </TableRow>
                                    </TableHeader>
                                    <TableBody>
                                        {purchases.map((purchase) => (
                                            <TableRow key={purchase.id}>
                                                <TableCell className="font-medium">{purchase.packageName}</TableCell>
                                                <TableCell className="hidden capitalize text-muted-foreground sm:table-cell">{purchase.type ?? '—'}</TableCell>
                                                <TableCell className="hidden text-muted-foreground md:table-cell">{purchase.provider ?? 'Checkout'}</TableCell>
                                                <TableCell className="hidden text-muted-foreground md:table-cell">{formatDate(purchase.purchasedAt)}</TableCell>
                                                <TableCell className="text-right font-medium">{formatPrice(purchase.price)}</TableCell>
                                            </TableRow>
                                        ))}
                                    </TableBody>
                                </Table>
                            )}
                        </div>
                    </CardContent>
                </Card>
            </div>

            <div className="grid gap-6 lg:grid-cols-2">
                <Card className="border border-muted-foreground/30 bg-white/95 dark:bg-gray-950/50">
                    <CardHeader>
                        <CardTitle>{t('export.title')}</CardTitle>
                        <p className="text-sm text-muted-foreground">{t('export.description')}</p>
                    </CardHeader>
                    <CardContent className="space-y-4">
                        {dataExportInfo.exports.length === 0 ? (
                            <p className="text-sm text-muted-foreground">{t('export.empty')}</p>
                        ) : (
                            <Table>
                                <TableHeader>
                                    <TableRow>
                                        <TableHead>{t('export.table.status')}</TableHead>
                                        <TableHead>{t('export.table.created')}</TableHead>
                                        <TableHead className="hidden md:table-cell">{t('export.table.expires')}</TableHead>
                                        <TableHead className="hidden lg:table-cell">{t('export.table.size')}</TableHead>
                                        <TableHead className="text-right">{t('export.table.action')}</TableHead>
                                    </TableRow>
                                </TableHeader>
                                <TableBody>
                                    {dataExportInfo.exports.map((item) => (
                                        <TableRow key={item.id}>
                                            <TableCell className="font-medium">{formatExportStatus(item.status)}</TableCell>
                                            <TableCell>{formatDate(item.created_at)}</TableCell>
                                            <TableCell className="hidden md:table-cell">{formatDate(item.expires_at)}</TableCell>
                                            <TableCell className="hidden lg:table-cell">{formatBytes(item.size)}</TableCell>
                                            <TableCell className="text-right">
                                                {item.download_url && item.status === 'ready' ? (
                                                    <a
                                                        href={item.download_url}
                                                        className="text-sm font-semibold text-pink-600 transition hover:text-pink-700"
                                                    >
                                                        {t('export.download')}
                                                    </a>
                                                ) : item.status === 'failed' && item.error_message ? (
                                                    <span className="text-xs text-destructive">{t('export.failed_reason', { reason: item.error_message })}</span>
                                                ) : (
                                                    <span className="text-xs text-muted-foreground">—</span>
                                                )}
                                            </TableCell>
                                        </TableRow>
                                    ))}
                                </TableBody>
                            </Table>
                        )}

                        {dataExportInfo.hasPending && (
                            <Alert variant="default" className="border-dashed border-muted-foreground/30 bg-muted/20">
                                <AlertTitle>{t('export.pending_alert_title')}</AlertTitle>
                                <AlertDescription>{t('export.pending_alert_body')}</AlertDescription>
                            </Alert>
                        )}

                        {!canRequestExport && nextRequestDeadline && (
                            <p className="text-xs text-muted-foreground">
                                {t('export.cooldown', {
                                    date: nextRequestDeadline.toLocaleDateString(locale ?? 'de-DE'),
                                })}
                            </p>
                        )}
                    </CardContent>
                    <CardFooter>
                        <Button onClick={handleExportRequest} disabled={!canRequestExport}>
                            {t('export.button')}
                        </Button>
                    </CardFooter>
                </Card>

                <Card className="border border-red-200 bg-red-50/60 dark:border-red-900/60 dark:bg-red-950/20">
                    <CardHeader>
                        <CardTitle>{t('delete.title')}</CardTitle>
                        <p className="text-sm text-muted-foreground">{t('delete.description')}</p>
                    </CardHeader>
                    <CardContent className="space-y-4">
                        <Alert variant="destructive">
                            <AlertTitle>{t('delete.warning_title')}</AlertTitle>
                            <AlertDescription>{t('delete.warning_body')}</AlertDescription>
                        </Alert>

                        <form onSubmit={handleDeleteSubmit} className="space-y-3">
                            <div className="grid gap-2">
                                <Label htmlFor="confirmation">{t('delete.confirmation_label')}</Label>
                                <Input
                                    id="confirmation"
                                    name="confirmation"
                                    value={deleteForm.data.confirmation}
                                    onChange={(event) => deleteForm.setData('confirmation', event.target.value.toUpperCase())}
                                    placeholder={t('delete.confirmation_placeholder')}
                                />
                                <p className="text-xs text-muted-foreground">{t('delete.confirmation_hint')}</p>
                                <InputError message={deleteForm.errors.confirmation} />
                            </div>

                            <Button type="submit" variant="destructive" className="w-full" disabled={deleteForm.processing}>
                                {t('delete.button')}
                            </Button>
                        </form>
                    </CardContent>
                </Card>
            </div>
        </AppLayout>
    );
}

function AccountForm({ userData, localeOptions }: { userData: ProfilePageProps['userData']; localeOptions: Array<{ label: string; value: string }> }) {
    return (
        <>
            <CardHeader>
                <CardTitle>Profilinformationen</CardTitle>
                <p className="text-sm text-muted-foreground">Aktualisiere deine Kontaktdaten und die Standardsprache für E-Mails und Oberfläche.</p>
            </CardHeader>
            <CardContent>
                <Form
                    {...ProfileController.update.form()}
                    options={{ preserveScroll: true }}
                    className="space-y-6"
                >
                    {({ processing, recentlySuccessful, errors }) => (
                        <>
                            <div className="grid gap-2">
                                <Label htmlFor="name">Vollständiger Name</Label>
                                <Input id="name" name="name" defaultValue={userData.name ?? ''} autoComplete="name" placeholder="Max Mustermann" />
                                <InputError message={errors.name} />
                            </div>

                            <div className="grid gap-2">
                                <Label htmlFor="email">E-Mail-Adresse</Label>
                                <Input id="email" type="email" name="email" defaultValue={userData.email ?? ''} autoComplete="username" />
                                <InputError message={errors.email} />
                            </div>

                            <div className="grid gap-2">
                                <Label htmlFor="username">Benutzername</Label>
                                <Input id="username" name="username" defaultValue={userData.username ?? ''} autoComplete="username" placeholder="mein-eventname" />
                                <InputError message={errors.username} />
                            </div>

                            <div className="grid gap-2">
                                <Label htmlFor="preferred_locale">Bevorzugte Sprache</Label>
                                <select
                                    id="preferred_locale"
                                    name="preferred_locale"
                                    defaultValue={userData.preferredLocale ?? localeOptions[0]?.value ?? 'de'}
                                    className="mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
                                >
                                    {localeOptions.map((option) => (
                                        <option key={option.value} value={option.value}>
                                            {option.label}
                                        </option>
                                    ))}
                                </select>
                                <InputError message={errors.preferred_locale} />
                            </div>

                            <CardFooter className="px-0">
                                <div className="flex items-center gap-4">
                                    <Button disabled={processing}>Änderungen speichern</Button>
                                    <Transition
                                        show={recentlySuccessful}
                                        enter="transition ease-in-out"
                                        enterFrom="opacity-0"
                                        leave="transition ease-in-out"
                                        leaveTo="opacity-0"
                                    >
                                        <p className="text-sm text-muted-foreground">Gespeichert</p>
                                    </Transition>
                                </div>
                            </CardFooter>
                        </>
                    )}
                </Form>
            </CardContent>
        </>
    );
}

function PasswordForm() {
    const passwordInputRef = useRef<HTMLInputElement>(null);
    const currentPasswordInputRef = useRef<HTMLInputElement>(null);

    return (
        <>
            <CardHeader>
                <CardTitle>Sicherheit &amp; Passwort</CardTitle>
                <p className="text-sm text-muted-foreground">Vergebe ein starkes Passwort, um dein Konto bestmöglich zu schützen.</p>
            </CardHeader>
            <CardContent>
                <Form
                    {...PasswordController.update.form()}
                    options={{ preserveScroll: true }}
                    resetOnError={['password', 'password_confirmation', 'current_password']}
                    resetOnSuccess
                    onError={(errors) => {
                        if (errors.password) {
                            passwordInputRef.current?.focus();
                        }
                        if (errors.current_password) {
                            currentPasswordInputRef.current?.focus();
                        }
                    }}
                    className="space-y-6"
                >
                    {({ errors, processing, recentlySuccessful }) => (
                        <>
                            <div className="grid gap-2">
                                <Label htmlFor="current_password">Aktuelles Passwort</Label>
                                <Input id="current_password" name="current_password" type="password" ref={currentPasswordInputRef} autoComplete="current-password" />
                                <InputError message={errors.current_password} />
                            </div>

                            <div className="grid gap-2">
                                <Label htmlFor="password">Neues Passwort</Label>
                                <Input id="password" name="password" type="password" ref={passwordInputRef} autoComplete="new-password" />
                                <InputError message={errors.password} />
                            </div>

                            <div className="grid gap-2">
                                <Label htmlFor="password_confirmation">Bestätigung</Label>
                                <Input id="password_confirmation" name="password_confirmation" type="password" autoComplete="new-password" />
                                <InputError message={errors.password_confirmation} />
                            </div>

                            <CardFooter className="px-0">
                                <div className="flex items-center gap-4">
                                    <Button disabled={processing}>Passwort speichern</Button>
                                    <Transition
                                        show={recentlySuccessful}
                                        enter="transition ease-in-out"
                                        enterFrom="opacity-0"
                                        leave="transition ease-in-out"
                                        leaveTo="opacity-0"
                                    >
                                        <p className="text-sm text-muted-foreground">Aktualisiert</p>
                                    </Transition>
                                </div>
                            </CardFooter>
                        </>
                    )}
                </Form>
            </CardContent>
        </>
    );
}
