import React, { useState, useEffect, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { ColumnDef } from '@tanstack/react-table';
import { Link } from 'react-router-dom';
import { useAudit } from '@/hooks/useAudit';
import { useAdmin, useAdmins } from '@/hooks/useAdmins';
import { useUser } from '@/hooks/useUsers';
import { useEvent } from '@/hooks/useEvents';
import { AuditRecord, AuditListParams } from '@/types/api';
import { getSavedPageSize } from '@/utils/tablePagination';
import { DataTable } from '@/components/data-table/DataTable';
import { ListPageHeader } from '@/components/ListPageHeader';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Badge } from '@/components/ui/badge';
import { Skeleton } from '@/components/ui/skeleton';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';

const TABLE_KEY = 'audit';
const ALL = '__all__';

const roleBadgeVariant = (role: string) => {
    if (role === 'superadmin') return 'destructive' as const;
    if (role === 'admin') return 'default' as const;
    if (role === 'moderator') return 'secondary' as const;
    return 'outline' as const;
};

const actionBadgeVariant = (action: string) => {
    if (action === 'create') return 'success' as const;
    if (action === 'delete') return 'destructive' as const;
    if (action === 'update') return 'default' as const;
    if (action === 'freeze' || action === 'block' || action === 'hide') return 'warning' as const;
    return 'outline' as const;
};

const entityTypeBadgeVariant = (type: string) => {
    if (type === 'user') return 'default' as const;
    if (type === 'event') return 'success' as const;
    if (type === 'review') return 'secondary' as const;
    if (type === 'report') return 'destructive' as const;
    return 'outline' as const;
};

const isBadValue = (val: unknown) =>
    val === '-' || val === 'undefined' || val === '' || val === null || val === undefined;

const toDateInput = (iso: string | undefined): string => {
    if (!iso) return '';
    return iso.slice(0, 10);
};

const dateToIso = (date: string, endOfDay = false): string | undefined => {
    if (!date) return undefined;
    const d = new Date(date);
    if (endOfDay) d.setHours(23, 59, 59, 999);
    else d.setHours(0, 0, 0, 0);
    return d.toISOString();
};

const AdminCell: React.FC<{ adminId: string }> = ({ adminId }) => {
    const { data: admin, isLoading: loading } = useAdmin(adminId);
    if (loading) return <Skeleton className="h-4 w-24" />;
    if (!admin) return <span>{adminId}</span>;
    const name = admin.nickname && admin.nickname !== '-' ? admin.nickname : admin.email;
    return <Link to={`/admins/${admin.id}`}>{name || admin.id}</Link>;
};

const EntityNameCell: React.FC<{ entityType: string; entityId: string }> = ({ entityType, entityId }) => {
    const { data: user, isLoading: loadingUser } = useUser(entityType === 'user' ? entityId : '');
    const { data: event, isLoading: loadingEvent } = useEvent(entityType === 'event' ? entityId : '');

    if (entityType === 'user') {
        if (loadingUser) return <Skeleton className="h-4 w-24" />;
        if (!user) return <span>{entityId}</span>;
        const name = !isBadValue(user.nickname) ? user.nickname : user.email;
        return <Link to={`/users/${user.id}`}>{!isBadValue(name) ? name : user.id}</Link>;
    }

    if (entityType === 'event') {
        if (loadingEvent) return <Skeleton className="h-4 w-24" />;
        if (!event) return <span>{entityId}</span>;
        const name = !isBadValue(event.title) ? event.title : event.id;
        return <Link to={`/events/${event.id}`}>{name}</Link>;
    }

    if (entityType === 'review') {
        return <Link to={`/reviews/${entityId}`}>{entityId}</Link>;
    }

    return <span>{entityId}</span>;
};

const AuditPage: React.FC = () => {
    const { t } = useTranslation();
    const [params, setParams] = useState<AuditListParams>({
        limit: getSavedPageSize(TABLE_KEY),
        offset: 0,
        sort: 'timestamp',
        order: 'desc',
    });
    const { data, isLoading } = useAudit(params);
    const { data: admins, isLoading: loadingAdmins } = useAdmins({ limit: 1000, offset: 0 });
    const [uniqueActions, setUniqueActions] = useState<string[]>([]);
    const [adminSearch, setAdminSearch] = useState('');

    useEffect(() => {
        if (data?.data) {
            const actions = new Set(data.data.map((record) => record.action).filter(Boolean));
            setUniqueActions((prev) => {
                const merged = new Set([...prev, ...actions]);
                return Array.from(merged).sort();
            });
        }
    }, [data]);

    const filteredAdmins = useMemo(() => {
        const list = admins?.data || [];
        if (!adminSearch.trim()) return list;
        const q = adminSearch.toLowerCase();
        return list.filter((a) => (a.email || a.id).toLowerCase().includes(q));
    }, [admins, adminSearch]);

    const columns = useMemo<ColumnDef<AuditRecord>[]>(
        () => [
            {
                id: 'admin',
                header: t('audit.admin'),
                enableSorting: false,
                cell: ({ row }) => <AdminCell adminId={row.original.admin_id} />,
            },
            {
                accessorKey: 'role',
                header: t('common.role'),
                enableSorting: true,
                cell: ({ getValue }) => {
                    const role = getValue<string>();
                    return <Badge variant={roleBadgeVariant(role)}>{role}</Badge>;
                },
            },
            {
                accessorKey: 'action',
                header: t('audit.action'),
                enableSorting: true,
                cell: ({ getValue }) => {
                    const action = getValue<string>();
                    return <Badge variant={actionBadgeVariant(action)}>{action}</Badge>;
                },
            },
            {
                accessorKey: 'entity_type',
                header: t('common.type'),
                enableSorting: true,
                cell: ({ getValue }) => {
                    const type = getValue<string>();
                    return <Badge variant={entityTypeBadgeVariant(type)}>{type}</Badge>;
                },
            },
            {
                id: 'entity_name',
                header: t('audit.name'),
                enableSorting: false,
                cell: ({ row }) => (
                    <EntityNameCell entityType={row.original.entity_type} entityId={row.original.entity_id} />
                ),
            },
            { accessorKey: 'timestamp', header: t('common.date'), enableSorting: true },
            { accessorKey: 'ip', header: t('common.ip'), enableSorting: false },
            {
                accessorKey: 'reason',
                header: t('common.reason'),
                enableSorting: false,
                cell: ({ getValue }) => {
                    const reason = getValue<string>();
                    return <span className="line-clamp-2">{reason}</span>;
                },
            },
        ],
        [t]
    );

    return (
        <div className="space-y-6">
            <ListPageHeader title={t('audit.title')} description={t('audit.description')} />

            <div className="flex flex-wrap items-end gap-4">
                <div className="space-y-2">
                    <Label>{t('audit.searchAdmin')}</Label>
                    <Input
                        placeholder={t('audit.searchAdminPlaceholder')}
                        value={adminSearch}
                        onChange={(e) => setAdminSearch(e.target.value)}
                        className="w-[200px]"
                    />
                </div>
                <div className="space-y-2">
                    <Label>{t('audit.admin')}</Label>
                    <Select
                        value={params.admin_id ?? ALL}
                        onValueChange={(val) =>
                            setParams((prev) => ({ ...prev, admin_id: val === ALL ? undefined : val, offset: 0 }))
                        }
                        disabled={loadingAdmins}
                    >
                        <SelectTrigger className="w-[250px]">
                            <SelectValue placeholder={t('common.selectAdmin')} />
                        </SelectTrigger>
                        <SelectContent>
                            <SelectItem value={ALL}>{t('common.all')}</SelectItem>
                            {filteredAdmins.map((admin) => {
                                const label = admin.email || admin.id;
                                return (
                                    <SelectItem key={admin.id} value={admin.id}>
                                        {label}
                                    </SelectItem>
                                );
                            })}
                        </SelectContent>
                    </Select>
                </div>
                <div className="space-y-2">
                    <Label>{t('audit.action')}</Label>
                    <Select
                        value={params.action ?? ALL}
                        onValueChange={(val) =>
                            setParams((prev) => ({ ...prev, action: val === ALL ? undefined : val, offset: 0 }))
                        }
                    >
                        <SelectTrigger className="w-[200px]">
                            <SelectValue placeholder={t('audit.action')} />
                        </SelectTrigger>
                        <SelectContent>
                            <SelectItem value={ALL}>{t('common.all')}</SelectItem>
                            {uniqueActions.map((action) => (
                                <SelectItem key={action} value={action}>
                                    {action}
                                </SelectItem>
                            ))}
                        </SelectContent>
                    </Select>
                </div>
                <div className="space-y-2">
                    <Label>{t('common.dateFrom')}</Label>
                    <Input
                        type="date"
                        value={toDateInput(params.date_from)}
                        onChange={(e) =>
                            setParams((prev) => ({
                                ...prev,
                                date_from: dateToIso(e.target.value, false),
                                offset: 0,
                            }))
                        }
                        className="w-[160px]"
                    />
                </div>
                <div className="space-y-2">
                    <Label>{t('common.dateTo')}</Label>
                    <Input
                        type="date"
                        value={toDateInput(params.date_to)}
                        onChange={(e) =>
                            setParams((prev) => ({
                                ...prev,
                                date_to: dateToIso(e.target.value, true),
                                offset: 0,
                            }))
                        }
                        className="w-[160px]"
                    />
                </div>
            </div>

            <DataTable
                columns={columns}
                data={data?.data ?? []}
                total={data?.total}
                isLoading={isLoading}
                tableKey={TABLE_KEY}
                params={params}
                onParamsChange={setParams}
            />
        </div>
    );
};

export default AuditPage;
