import { DataTable } from '@/components/datatable';
import StatisticCardLarge from '@/components/dashboard/StatisticCardLarge';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardTitle } from '@/components/ui/card';
import AppLayout from '@/layouts/app-layout';
import type { PaginatedData } from '@/types';
import { Head, router } from '@inertiajs/react';
import { ColumnDef } from '@tanstack/react-table';
import { format } from 'date-fns';
import {
    AlertTriangle,
    CheckCircle2,
    Clock,
    Cloud,
    Database,
    Download,
    FileArchive,
    FileText,
    FolderArchive,
    HardDrive,
    TrendingUp,
    User,
} from 'lucide-react';
import type { ReactNode } from 'react';

type BackupItem = {
    path: string;
    basename: string;
    size: number;
    last_modified: number;
    ext: string;
    user_name?: string;
    created_at?: string | null;
};
type BackupDb = {
    id: number;
    mode: 'manual' | 'auto';
    category: 'database' | 'files';
    s3_url?: string | null;
    local_path: string | null;
    s3_path: string | null;
    google_path: string | null;
    size_bytes: number | null;
    success: boolean;
    s3_ok: boolean;
    google_ok: boolean;
    created_at: string | null;
    user?: { id: number; name: string; email: string } | null;
};
type BackupStats = {
    total: number;
    success: number;
    failed: number;
    manual: number;
    auto: number;
    database: number;
    files: number;
    storage_present: number;
    s3_ok: number;
    google_ok: number;
    size_total: number;
    latest_at: string | null;
    last_backup?: { date: string; type: 'database' | 'files'; mode: 'manual' | 'auto'; status: 'success' | 'failed'; size: number | null } | null;
    next_scheduled?: string | null;
    storage_status?: { local_root: string; total_size: number; s3_ok: number; google_ok: number };
    recent_error?: { date: string; message?: string | null } | null;
};
type Props = { backups: { manual: BackupItem[]; auto: BackupItem[] }; backupsDb: PaginatedData<BackupDb>; backupStats: BackupStats };

export default function Index({ backups, backupsDb, backupStats }: Props) {
    const runManual = (opts: { db?: boolean; files?: boolean }) => {
        const form = new FormData();
        if (opts.db !== undefined) form.append('db', String(opts.db));
        if (opts.files !== undefined) form.append('files', String(opts.files));
        router.post(route('backup.manual'), form, { preserveScroll: true });
    };

    const formatBytes = (bytes: number) => {
        if (!bytes && bytes !== 0) return '-';
        const sizes = ['B', 'KB', 'MB', 'GB'];
        if (bytes === 0) return '0 B';
        const i = Math.floor(Math.log(bytes) / Math.log(1024));
        const val = bytes / Math.pow(1024, i);
        return `${val.toFixed(val >= 100 ? 0 : 1)} ${sizes[i]}`;
    };

    const formatWhen = (ts?: number) => {
        try {
            if (!ts) return '';
            return format(new Date(ts * 1000), 'MMM dd, yyyy HH:mm');
        } catch {
            return '';
        }
    };

    const formatDate = (iso?: string | null) => {
        if (!iso) return '';
        try {
            return format(new Date(iso), 'MMM dd, yyyy HH:mm');
        } catch {
            return '';
        }
    };

    const renderCards = (items: BackupItem[]) => {
        if (!items || items.length === 0) return <p className="text-sm text-gray-500">No backups yet.</p>;
        return (
            <div className="grid grid-cols-1 gap-3 md:grid-cols-2">
                {items.map((f) => (
                    <Card key={f.path} className="rounded-lg border">
                        <CardContent className="p-4">
                            <div className="flex items-start justify-between gap-3">
                                <div className="min-w-0">
                                    <div className="flex items-center gap-2">
                                        {f.ext === 'zip' ? (
                                            <FileArchive className="h-4 w-4 text-gray-500" />
                                        ) : (
                                            <FileText className="h-4 w-4 text-gray-500" />
                                        )}
                                        <span className="truncate font-mono" title={f.basename}>
                                            {f.basename}
                                        </span>
                                        <Badge variant="secondary" className="ml-2 uppercase">
                                            {f.ext}
                                        </Badge>
                                    </div>
                                    <div className="mt-2 space-x-3 text-xs text-gray-500">
                                        <span>{formatBytes(f.size)}</span>
                                        <span className="inline-flex items-center gap-1">
                                            <Clock className="h-3 w-3" /> {formatWhen(f.last_modified)}
                                        </span>
                                    </div>
                                </div>
                                <div className="text-right text-xs text-gray-500">
                                    <div>{f.user_name || '—'}</div>
                                    <div>{f.created_at ? formatDate(f.created_at) : ''}</div>
                                </div>
                            </div>
                        </CardContent>
                    </Card>
                ))}
            </div>
        );
    };

    const renderCompactRow = (f: BackupItem | null | undefined, emptyText: string) => {
        if (!f) return <div className="p-3 text-sm text-gray-500">{emptyText}</div>;
        return (
            <div className="flex items-center justify-between p-3 transition-colors hover:bg-gray-50">
                <div className="flex min-w-0 items-center gap-2">
                    {f.ext === 'zip' ? (
                        <FileArchive className="h-4 w-4 shrink-0 text-orange-500" />
                    ) : (
                        <FileText className="h-4 w-4 shrink-0 text-blue-500" />
                    )}
                    <span className="truncate font-mono text-sm font-medium" title={f.basename}>
                        {f.basename}
                    </span>
                    <Badge variant="secondary" className="ml-2 shrink-0 uppercase">
                        {f.ext}
                    </Badge>
                </div>
                <div className="flex shrink-0 items-center gap-6 text-xs text-gray-500">
                    <span>{formatBytes(f.size)}</span>
                    <span className="inline-flex items-center gap-1">
                        <Clock className="h-3 w-3" /> {formatWhen(f.last_modified)}
                    </span>
                    {(f.user_name || f.created_at) && (
                        <div className="text-right">
                            <div className="font-medium">{f.user_name || '—'}</div>
                            <div>{f.created_at ? formatDate(f.created_at) : ''}</div>
                        </div>
                    )}
                </div>
            </div>
        );
    };

    // Latest items per mode/type
    const pickLatestByExt = (items: BackupItem[], ext: 'sql' | 'zip') =>
        (items || []).filter((i) => i.ext === ext).sort((a, b) => b.last_modified - a.last_modified)[0];
    const lastManualDb = pickLatestByExt(backups?.manual || [], 'sql');
    const lastManualFiles = pickLatestByExt(backups?.manual || [], 'zip');
    const lastAutoDb = pickLatestByExt(backups?.auto || [], 'sql');
    const lastAutoFiles = pickLatestByExt(backups?.auto || [], 'zip');

    // (deduped above) latest entries computed once

    const renderSlimSqlRow = (f: BackupItem | null | undefined, emptyText: string) => {
        if (!f) return <p className="text-sm text-gray-500">{emptyText}</p>;
        return (
            <div className="space-y-1 text-sm">
                <div className="font-medium">SQL {formatBytes(f.size)}</div>
                <div className="text-gray-500">{f.user_name || '—'}</div>
                <div className="text-gray-500">{f.created_at ? formatDate(f.created_at) : formatWhen(f.last_modified)}</div>
            </div>
        );
    };

    const renderSlimBadgedRow = (f: BackupItem | null | undefined, mode: 'manual' | 'auto', type: 'sql' | 'zip', emptyText: string) => {
        if (!f) return <p className="text-sm text-gray-500">{emptyText}</p>;
        const typeLabel = type.toUpperCase();
        const modeLabel = mode.toUpperCase();
        return (
            <div className="space-y-1 text-sm">
                <div className="flex items-center gap-2">
                    <Badge variant="outline" className="uppercase">
                        {modeLabel}
                    </Badge>
                    <Badge variant="secondary" className="text-white uppercase">
                        {typeLabel}
                    </Badge>
                    <span className="text-gray-500">{formatBytes(f.size)}</span>
                </div>
                <div className="flex items-center gap-1 text-gray-500">
                    <User className="h-3 w-3" />
                    <span>{f.user_name || '—'}</span>
                </div>
                <div className="flex items-center gap-1 text-gray-500">
                    <Clock className="h-3 w-3" />
                    <span>
                        {f.created_at
                            ? formatDate(f.created_at) // ISO string
                            : f.last_modified
                                ? formatWhen(f.last_modified) // Unix timestamp in seconds
                                : '-'}
                    </span>
                </div>
            </div>
        );
    };

    // DataTable columns for Backup History
    const historyColumns: (ColumnDef<BackupDb> & { enable_sorting?: boolean })[] = [
        {
            id: 'when',
            header: 'When',
            cell: ({ row }) => <span className="whitespace-nowrap">{formatDate(row.original.created_at)}</span>,
        },
        {
            id: 'mode',
            header: 'Mode',
            cell: ({ row }) => (
                <Badge variant="secondary" className="text-white uppercase">
                    {row.original.mode}
                </Badge>
            ),
        },
        {
            id: 'category',
            header: 'Category',
            cell: ({ row }) => <Badge className="text-white uppercase">{row.original.category}</Badge>,
        },
        {
            id: 'by',
            header: 'By',
            cell: ({ row }) => <span className="whitespace-nowrap">{row.original.user?.name || '—'}</span>,
        },
        {
            id: 'size',
            header: 'Size',
            cell: ({ row }) => <span className="whitespace-nowrap">{formatBytes(row.original.size_bytes ?? 0)}</span>,
        },
        {
            id: 'storage',
            header: 'Storage',
            cell: ({ row }) =>
                row.original.local_path ? (
                    <div className="flex items-center gap-2">
                        <Button asChild size="sm" variant="ghost" className="flex items-center gap-1">
                            <a href={route('backup.download', { backup: row.original.id, disk: 'local' })}>
                                <Download className="h-4 w-4" /> Download
                            </a>
                        </Button>
                    </div>
                ) : (
                    <Badge variant="destructive">Missing</Badge>
                ),
        },
        {
            id: 's3',
            header: 'Cloud',
            cell: ({ row }) =>
                row.original.s3_path ? (
                    <div className="flex items-center gap-2">
                        <Button asChild size="sm" variant="ghost" className="flex items-center gap-1">
                            <a href={route('backup.download', { backup: row.original.id, disk: 's3' })}>
                                <Download className="h-4 w-4" /> Download
                            </a>
                        </Button>
                    </div>
                ) : (
                    <span className="text-gray-500">—</span>
                ),
        },
        {
            id: 'status',
            header: 'Status',
            cell: ({ row }) =>
                row.original.success ? (
                    <Badge variant="secondary" className="border-green-200 bg-green-100 text-green-800">
                        OK
                    </Badge>
                ) : (
                    <Badge variant="destructive">Failed</Badge>
                ),
        },
    ];

    return (
        <>
            <Head title="Backup" />
            <div className="no-scrollbar rounded-xl bg-gray-100/55 p-2 sm:p-4">
                {/* Header */}
                <div className="mb-6 grid grid-cols-1 gap-1">
                    <h2 className="text-xl font-bold sm:text-2xl">Backups logs</h2>
                    <div className="flex items-center text-sm text-gray-600">
                        <span>System</span>
                        <span className="mx-2">›</span>
                        <span>Backups Logs</span>
                    </div>
                </div>

                <div className="flex flex-col space-y-4 pb-8">
                    {/* Section 1: Top backup statistics (4 cards) */}
                    <div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-4">
                        <StatisticCardLarge
                            title="Last Backup"
                            value={backupStats?.last_backup ? formatDate(backupStats.last_backup.date) : '—'}
                            change={
                                backupStats?.last_backup
                                    ? `${backupStats.last_backup.mode} · ${backupStats.last_backup.type} · ${formatBytes(backupStats.last_backup.size || 0)}`
                                    : undefined
                            }
                            changeType={backupStats?.last_backup?.status === 'success' ? 'up' : backupStats?.last_backup ? 'down' : 'neutral'}
                            icon={Clock}
                            iconBg="bg-blue-100"
                            iconColor="text-blue-600"
                        />
                        <StatisticCardLarge
                            title="Success Rate"
                            value={`${(backupStats?.total ?? 0) > 0
                                    ? Math.round(((backupStats?.success ?? 0) / (backupStats?.total ?? 1)) * 100)
                                    : 0
                                }%`}
                            change={`${backupStats?.success ?? 0} ok · ${backupStats?.failed ?? 0} failed · Total: ${backupStats?.total ?? 0}`}
                            changeType={
                                (backupStats?.total ?? 0) === 0
                                    ? 'neutral'
                                    : Math.round(((backupStats?.success ?? 0) / (backupStats?.total ?? 1)) * 100) >= 80
                                        ? 'up'
                                        : 'down'
                            }
                            icon={TrendingUp}
                            iconBg="bg-emerald-100"
                            iconColor="text-emerald-600"
                        />
                        <StatisticCardLarge
                            title="Storage Used"
                            value={formatBytes(backupStats?.storage_status?.total_size || 0)}
                            change={`S3: ${backupStats?.storage_status?.s3_ok ?? 0} · Google: ${backupStats?.storage_status?.google_ok ?? 0}`}
                            changeType="neutral"
                            icon={HardDrive}
                            iconBg="bg-violet-100"
                            iconColor="text-violet-600"
                        />
                        <StatisticCardLarge
                            title="Recent Errors"
                            value={backupStats?.recent_error ? formatDate(backupStats.recent_error.date) : 'All Clear'}
                            change={backupStats?.recent_error ? (backupStats.recent_error.message || '—') : 'No recent errors detected'}
                            changeType={backupStats?.recent_error ? 'down' : 'up'}
                            icon={backupStats?.recent_error ? AlertTriangle : CheckCircle2}
                            iconBg={backupStats?.recent_error ? 'bg-rose-100' : 'bg-emerald-100'}
                            iconColor={backupStats?.recent_error ? 'text-rose-600' : 'text-emerald-600'}
                        />
                    </div>

                    {/* Section 2: Actions (left) + Recent Backups (right) */}
                    <div className="grid grid-cols-1 gap-4 lg:grid-cols-2">
                        {/* Backup Actions */}
                        <Card className="border-gray-100 shadow-sm">
                            <CardContent className="p-4">
                                <div className="flex items-start justify-between">
                                    <CardTitle className="flex items-center gap-2 text-base font-semibold text-gray-800">
                                        <Database className="h-4 w-4" /> Backup Actions
                                    </CardTitle>
                                </div>
                                <div className="mt-4 space-y-4">
                                    <p className="text-sm text-gray-500">
                                        Manually trigger a database or files backup at any time.
                                    </p>
                                    <div className="flex flex-wrap gap-2">
                                        <Button
                                            onClick={() => runManual({ db: true, files: false })}
                                            className="cursor-pointer transition-transform duration-150 active:scale-95 active:bg-blue-700"
                                        >
                                            Run DB Backup
                                        </Button>

                                        <Button
                                            variant="secondary"
                                            onClick={() => runManual({ files: true, db: false })}
                                            className="cursor-pointer text-white transition-transform duration-150 active:scale-95 active:bg-gray-600"
                                        >
                                            <FolderArchive className="mr-1 h-4 w-4" /> Run Files Backup
                                        </Button>

                                        <Button
                                            variant="outline"
                                            onClick={() => runManual({ db: true, files: true })}
                                            className="cursor-pointer transition-transform duration-150 active:scale-95 active:bg-gray-200"
                                        >
                                            Run Both
                                        </Button>
                                    </div>

                                    <div className="rounded-md bg-gray-100/60 p-3 text-xs text-gray-500">
                                        Backups are stored under <code className="font-mono">storage/app/private/backup</code> and uploaded to your
                                        configured S3 and Google Drive disks.
                                    </div>
                                </div>
                            </CardContent>
                        </Card>

                        {/* Recent Backups (Local FS) - compact, consistent styling */}
                        <Card className="border-gray-100 shadow-sm">
                            <CardContent className="p-4">
                                <div className="flex items-start justify-between">
                                    <CardTitle className="text-base font-semibold text-gray-800">Recent Backups (Local FS)</CardTitle>
                                </div>
                                <p className="mt-1 text-sm text-gray-500">
                                    Latest local backup files for each mode and type.
                                </p>

                                <div className="mt-4 space-y-6">
                                    {/* Row 1: Manual (SQL, ZIP) */}
                                    <div>
                                        <h3 className="mb-2 text-sm font-semibold">Manual</h3>
                                        <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
                                            {renderSlimBadgedRow(lastManualDb, 'manual', 'sql', 'No recent manual SQL backup.')}
                                            {renderSlimBadgedRow(lastManualFiles, 'manual', 'zip', 'No recent manual ZIP backup.')}
                                        </div>
                                    </div>

                                    {/* Row 2: Automatic (SQL, ZIP) */}
                                    <div>
                                        <h3 className="mb-2 text-sm font-semibold">Automatic</h3>
                                        <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
                                            {renderSlimBadgedRow(lastAutoDb, 'auto', 'sql', 'No recent automatic SQL backup.')}
                                            {renderSlimBadgedRow(lastAutoFiles, 'auto', 'zip', 'No recent automatic ZIP backup.')}
                                        </div>
                                    </div>
                                </div>
                            </CardContent>
                        </Card>
                    </div>

                    {/* Section 3: Full-width History */}
                    <Card className="border-gray-100 shadow-sm">
                        <CardContent className="p-4">
                            <div className="flex items-start justify-between">
                                <CardTitle className="text-base font-semibold text-gray-800">History</CardTitle>
                            </div>
                            {!backupsDb || backupsDb.data.length === 0 ? (
                                <p className="text-sm text-gray-500">No backup records yet.</p>
                            ) : (
                                <div className="mt-4 w-96 sm:w-full">
                                    <DataTable
                                        columns={historyColumns}
                                        data={backupsDb.data}
                                        paginatedData={backupsDb}
                                        tableKey="backup-history"
                                        showToolbar={false}
                                    />
                                </div>
                            )}
                        </CardContent>
                    </Card>
                </div>
            </div>
        </>
    );
}

// Attach layout for Inertia page
Index.layout = (page: ReactNode) => (
    <AppLayout
        breadcrumbs={[
            { title: 'Home', href: '/' },
            { title: 'Settings', href: route('settings.company.edit') },
            { title: 'Backup', href: route('backup.index') },
        ]}
        title="Backup"
    >
        {page}
    </AppLayout>
);
