import React, { useState, useEffect, useRef, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import type { TFunction } from 'i18next';
import { ColumnDef } from '@tanstack/react-table';
import { Info, Pencil, Trash2 } from 'lucide-react';
import { Link, useNavigate } from 'react-router-dom';
import { useForm, Controller } from 'react-hook-form';
import { useCalendars, useUpdateCalendar, useDeleteCalendar, useCalendar, useCalendarStats } from '@/hooks/useCalendars';
import { useExploreView } from '@/hooks/useExploreView';
import { Calendar as CalendarType, CalendarListParams } from '@/types/api';
import { getSavedPageSize } from '@/utils/tablePagination';
import { formatStatusLabel } from '@/utils/statusLabels';
import { ExploreListShell } from '@/components/explore/ExploreListShell';
import { ExploreSearch } from '@/components/explore/ExploreSearch';
import { ExploreDataView } from '@/components/explore/ExploreDataView';
import { ExploreInsightsCollapse } from '@/components/explore/ExploreInsightsCollapse';
import { RowActionsMenu, type RowAction } from '@/components/explore/RowActionsMenu';
import type { DenseRowModel } from '@/components/explore/DenseRowList';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import { Badge } from '@/components/ui/badge';
import {
    Dialog,
    DialogContent,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import { Skeleton } from '@/components/ui/skeleton';
import { EntitySlideOver, type ExplorePreviewTarget } from '@/components/EntitySlideOver';

const TABLE_KEY = 'calendars';

const calendarTypeBadgeVariant = (type: string) => {
    if (type === 'commercial') return 'secondary' as const;
    return 'default' as const;
};

const calendarStatusVariant = (status: string) => {
    if (status === 'active') return 'default' as const;
    if (status === 'frozen') return 'secondary' as const;
    return 'destructive' as const;
};

interface EditFormValues {
    title?: string;
    description?: string;
    type?: string;
    status?: string;
    category?: string;
    reason?: string;
}

function calendarActions(
    handlers: {
        onOpen: () => void;
        onEdit: () => void;
        onDelete: () => void;
    },
    t: TFunction
): RowAction[] {
    return [
        { label: t('common.open'), icon: <Info className="h-4 w-4" />, onClick: handlers.onOpen },
        { label: t('common.edit'), icon: <Pencil className="h-4 w-4" />, onClick: handlers.onEdit },
        {
            label: t('common.delete'),
            icon: <Trash2 className="h-4 w-4" />,
            onClick: handlers.onDelete,
            destructive: true,
            separatorBefore: true,
        },
    ];
}

const CalendarListPage: React.FC = () => {
    const { t } = useTranslation();
    const navigate = useNavigate();
    const { viewMode, setViewMode } = useExploreView();
    const [preview, setPreview] = useState<ExplorePreviewTarget>(null);
    const [params, setParams] = useState<CalendarListParams>({
        limit: getSavedPageSize(TABLE_KEY),
        offset: 0,
        sort: 'created_at',
        order: 'desc',
    });
    const [searchDraft, setSearchDraft] = useState('');
    const { data, isLoading } = useCalendars(params);
    const { data: stats } = useCalendarStats();
    const updateCalendar = useUpdateCalendar();
    const deleteCalendar = useDeleteCalendar();

    const [editModal, setEditModal] = useState<{ open: boolean; calendarId: string | null }>({
        open: false,
        calendarId: null,
    });
    const { data: editingCalendar, isLoading: loadingCalendar } = useCalendar(editModal.calendarId || '');
    const editForm = useForm<EditFormValues>();
    const originalCalendarRef = useRef<CalendarType | null>(null);

    const [deleteConfirm, setDeleteConfirm] = useState<{ open: boolean; calendarId: string | null }>({
        open: false,
        calendarId: null,
    });

    const handleEdit = (id: string) => setEditModal({ open: true, calendarId: id });

    const handleSaveEdit = editForm.handleSubmit((values) => {
        if (!editModal.calendarId || !originalCalendarRef.current) return;
        const original = originalCalendarRef.current;
        const cleanedValues: Record<string, unknown> = {};

        // Only form fields — do not null-out entity keys absent from the form (e.g. id, owner_id).
        Object.keys(values).forEach((key) => {
            const newVal = (values as Record<string, unknown>)[key];
            if (newVal === '' || newVal === undefined || newVal === null) {
                const origVal = (original as unknown as Record<string, unknown>)[key];
                if (origVal && origVal !== '-' && origVal !== '' && origVal !== undefined && origVal !== null) {
                    cleanedValues[key] = null;
                }
                return;
            }
            if (newVal === '-') return;
            cleanedValues[key] = newVal;
        });

        const payload = Object.fromEntries(
            Object.entries(cleanedValues).filter(([key, v]) => {
                const origVal = (original as unknown as Record<string, unknown>)[key];
                return JSON.stringify(v) !== JSON.stringify(origVal === '-' ? undefined : origVal);
            })
        );

        updateCalendar.mutate(
            { id: editModal.calendarId, data: payload },
            { onSuccess: () => setEditModal({ open: false, calendarId: null }) }
        );
    });

    useEffect(() => {
        if (!editModal.open || loadingCalendar || !editingCalendar) return;
        originalCalendarRef.current = editingCalendar;
        const clean = (val: unknown) => (val === '-' || val === 'undefined' ? '' : val);
        editForm.reset({
            title: clean(editingCalendar.title) as string,
            description: clean(editingCalendar.description) as string,
            type: clean(editingCalendar.type) as string,
            status: clean(editingCalendar.status) as string,
            category: clean(editingCalendar.category) as string,
            reason: clean(editingCalendar.reason) as string,
        });
    }, [editingCalendar, editModal.open, loadingCalendar, editForm]);

    const handleDelete = (id: string) => setDeleteConfirm({ open: true, calendarId: id });

    const confirmDelete = () => {
        if (!deleteConfirm.calendarId) return;
        deleteCalendar.mutate(deleteConfirm.calendarId, {
            onSuccess: () => setDeleteConfirm({ open: false, calendarId: null }),
        });
    };

    const applySearch = () => {
        setParams((prev) => ({ ...prev, q: searchDraft.trim() || undefined, offset: 0 }));
    };

    const exploreStats = useMemo(() => {
        if (!stats) return [];
        const items = [{ label: t('common.total'), value: stats.total_calendars }];
        Object.entries(stats.calendars_by_status || {})
            .slice(0, 3)
            .forEach(([status, count]) => {
                items.push({ label: formatStatusLabel(status), value: count });
            });
        return items.slice(0, 4);
    }, [stats, t]);

    const columns = useMemo<ColumnDef<CalendarType>[]>(
        () => [
            {
                accessorKey: 'title',
                header: t('common.title'),
                enableSorting: true,
                cell: ({ row, getValue }) => (
                    <button
                        type="button"
                        className="text-left font-medium text-primary hover:underline"
                        onClick={() => setPreview({ type: 'calendar', id: row.original.id })}
                    >
                        {getValue<string>() || row.original.id}
                    </button>
                ),
            },
            {
                accessorKey: 'type',
                header: t('common.type'),
                size: 110,
                enableSorting: true,
                cell: ({ getValue }) => {
                    const type = getValue<string>();
                    return <Badge variant={calendarTypeBadgeVariant(type)}>{type}</Badge>;
                },
            },
            {
                accessorKey: 'status',
                header: t('common.status'),
                size: 100,
                enableSorting: true,
                cell: ({ getValue }) => {
                    const status = getValue<string>();
                    return <Badge variant={calendarStatusVariant(status)}>{formatStatusLabel(status)}</Badge>;
                },
            },
            {
                accessorKey: 'owner_id',
                header: t('common.owner'),
                enableSorting: false,
                cell: ({ getValue }) => {
                    const ownerId = getValue<string>();
                    return <Link to={`/users/${ownerId}`}>{ownerId}</Link>;
                },
            },
            {
                id: 'rating',
                header: t('common.rating'),
                size: 90,
                enableSorting: false,
                cell: ({ row }) => `${row.original.rating_avg} (${row.original.rating_count})`,
            },
            {
                id: 'actions',
                header: '',
                size: 48,
                enableSorting: false,
                cell: ({ row }) => {
                    const record = row.original;
                    return (
                        <RowActionsMenu
                            actions={calendarActions({
                                onOpen: () => navigate(`/calendars/${record.id}`),
                                onEdit: () => handleEdit(record.id),
                                onDelete: () => handleDelete(record.id),
                            }, t)}
                        />
                    );
                },
            },
        ],
        [navigate, t]
    );

    const editTitle = editForm.watch('title');
    const editStatus = editForm.watch('status');
    const editHasErrors = !editTitle || !editStatus;

    const denseRows = useMemo<DenseRowModel[]>(() => {
        return (data?.data ?? []).map((record) => ({
            id: record.id,
            title: record.title || record.id,
            subtitle: record.owner_id ? t('explore.ownerId', { id: record.owner_id }) : undefined,
            badges: (
                <>
                    <Badge variant={calendarTypeBadgeVariant(record.type)}>{record.type}</Badge>
                    <Badge variant={calendarStatusVariant(record.status)}>{formatStatusLabel(record.status)}</Badge>
                </>
            ),
            meta: `★ ${record.rating_avg} (${record.rating_count})`,
            onActivate: () => setPreview({ type: 'calendar', id: record.id }),
            actions: calendarActions({
                onOpen: () => navigate(`/calendars/${record.id}`),
                onEdit: () => handleEdit(record.id),
                onDelete: () => handleDelete(record.id),
            }, t),
        }));
    }, [data?.data, navigate, t]);

    return (
        <>
            <ExploreListShell
                data-testid="page-calendars"
                title={t('calendars.title')}
                stats={exploreStats}
                viewMode={viewMode}
                onViewModeChange={setViewMode}
                toolbar={
                    <ExploreSearch
                        data-testid="filter-calendars-search"
                        value={searchDraft}
                        onChange={setSearchDraft}
                        onSubmit={applySearch}
                        placeholder={t('explore.searchCalendars')}
                    >
                        <Select
                            value={params.status ?? 'all'}
                            onValueChange={(v) =>
                                setParams((prev) => ({
                                    ...prev,
                                    status: v === 'all' ? undefined : (v as CalendarListParams['status']),
                                    offset: 0,
                                }))
                            }
                        >
                            <SelectTrigger className="w-36">
                                <SelectValue placeholder={t('common.status')} />
                            </SelectTrigger>
                            <SelectContent>
                                <SelectItem value="all">{t('common.allStatuses')}</SelectItem>
                                <SelectItem value="active">active</SelectItem>
                                <SelectItem value="frozen">frozen</SelectItem>
                                <SelectItem value="deleted">deleted</SelectItem>
                            </SelectContent>
                        </Select>
                        <Select
                            value={params.type ?? 'all'}
                            onValueChange={(v) =>
                                setParams((prev) => ({
                                    ...prev,
                                    type: v === 'all' ? undefined : (v as CalendarListParams['type']),
                                    offset: 0,
                                }))
                            }
                        >
                            <SelectTrigger className="w-36">
                                <SelectValue placeholder={t('common.type')} />
                            </SelectTrigger>
                            <SelectContent>
                                <SelectItem value="all">{t('common.allTypes')}</SelectItem>
                                <SelectItem value="personal">personal</SelectItem>
                                <SelectItem value="commercial">commercial</SelectItem>
                            </SelectContent>
                        </Select>
                    </ExploreSearch>
                }
            >
                {stats && (
                    <ExploreInsightsCollapse
                        title={t('explore.tops')}
                        tabs={[
                            {
                                id: 'rating',
                                label: t('explore.byRating'),
                                rows: (stats.top_calendars_by_rating ?? []).map((row) => ({
                                    id: row.id,
                                    primary: <Link to={`/calendars/${row.id}`}>{row.title || row.id}</Link>,
                                    value: row.rating_avg,
                                })),
                            },
                            {
                                id: 'reviews',
                                label: t('explore.byReviews'),
                                rows: (stats.top_calendars_by_reviews ?? []).map((row) => ({
                                    id: row.id,
                                    primary: <Link to={`/calendars/${row.id}`}>{row.title || row.id}</Link>,
                                    value: row.rating_avg,
                                })),
                            },
                            {
                                id: 'positive',
                                label: t('explore.positive'),
                                rows: (stats.top_calendars_by_positive_reviews ?? []).map((row) => ({
                                    id: row.id,
                                    primary: <Link to={`/calendars/${row.id}`}>{row.title || row.id}</Link>,
                                    value: row.rating_avg,
                                })),
                            },
                            {
                                id: 'negative',
                                label: t('explore.negative'),
                                rows: (stats.top_calendars_by_negative_reviews ?? []).map((row) => ({
                                    id: row.id,
                                    primary: <Link to={`/calendars/${row.id}`}>{row.title || row.id}</Link>,
                                    value: row.rating_avg,
                                })),
                            },
                        ]}
                    />
                )}

                <ExploreDataView
                    viewMode={viewMode}
                    columns={columns}
                    data={data?.data ?? []}
                    denseRows={denseRows}
                    total={data?.total}
                    isLoading={isLoading}
                    tableKey={TABLE_KEY}
                    params={params}
                    onParamsChange={setParams}
                />
            </ExploreListShell>

            <Dialog open={editModal.open} onOpenChange={(open) => !open && setEditModal({ open: false, calendarId: null })}>
                <DialogContent className="max-w-lg" data-testid="dialog-edit-calendar">
                    <DialogHeader>
                        <DialogTitle>{t('calendars.editTitle')}</DialogTitle>
                    </DialogHeader>
                    {loadingCalendar ? (
                        <div className="space-y-3 py-4">
                            <Skeleton className="h-9 w-full" />
                            <Skeleton className="h-9 w-full" />
                        </div>
                    ) : (
                        <form id="edit-calendar-form" className="space-y-4" onSubmit={handleSaveEdit}>
                            <div className="space-y-2">
                                <Label>{t('common.title')}</Label>
                                <Input {...editForm.register('title', { required: true })} />
                            </div>
                            <div className="space-y-2">
                                <Label>{t('common.description')}</Label>
                                <Textarea rows={3} {...editForm.register('description')} />
                            </div>
                            <div className="space-y-2">
                                <Label>{t('common.type')}</Label>
                                <Controller
                                    name="type"
                                    control={editForm.control}
                                    render={({ field }) => (
                                        <Select value={field.value || undefined} onValueChange={field.onChange}>
                                            <SelectTrigger>
                                                <SelectValue placeholder={t('common.selectType')} />
                                            </SelectTrigger>
                                            <SelectContent>
                                                <SelectItem value="personal">personal</SelectItem>
                                                <SelectItem value="commercial">commercial</SelectItem>
                                            </SelectContent>
                                        </Select>
                                    )}
                                />
                            </div>
                            <div className="space-y-2">
                                <Label>{t('common.status')}</Label>
                                <Controller
                                    name="status"
                                    control={editForm.control}
                                    rules={{ required: true }}
                                    render={({ field }) => (
                                        <Select value={field.value || undefined} onValueChange={field.onChange}>
                                            <SelectTrigger>
                                                <SelectValue placeholder={t('common.selectStatus')} />
                                            </SelectTrigger>
                                            <SelectContent>
                                                <SelectItem value="active">active</SelectItem>
                                                <SelectItem value="frozen">frozen</SelectItem>
                                                <SelectItem value="deleted">deleted</SelectItem>
                                            </SelectContent>
                                        </Select>
                                    )}
                                />
                            </div>
                            <div className="space-y-2">
                                <Label>{t('common.category')}</Label>
                                <Input {...editForm.register('category')} />
                            </div>
                            <div className="space-y-2">
                                <Label>{t('common.reason')}</Label>
                                <Input {...editForm.register('reason')} />
                            </div>
                        </form>
                    )}
                    <DialogFooter>
                        <Button variant="outline" onClick={() => setEditModal({ open: false, calendarId: null })}>
                            {t('common.cancel')}
                        </Button>
                        <Button
                            type="submit"
                            form="edit-calendar-form"
                            data-testid="btn-save"
                            disabled={editHasErrors || updateCalendar.isPending}
                        >
                            {t('common.save')}
                        </Button>
                    </DialogFooter>
                </DialogContent>
            </Dialog>

            <Dialog open={deleteConfirm.open} onOpenChange={(open) => !open && setDeleteConfirm({ open: false, calendarId: null })}>
                <DialogContent data-testid="dialog-delete-calendar">
                    <DialogHeader>
                        <DialogTitle>{t('calendars.deleteTitle')}</DialogTitle>
                    </DialogHeader>
                    <p className="text-sm text-muted-foreground">{t('common.irreversible')}</p>
                    <DialogFooter>
                        <Button variant="outline" onClick={() => setDeleteConfirm({ open: false, calendarId: null })}>
                            {t('common.cancel')}
                        </Button>
                        <Button
                            variant="destructive"
                            data-testid="btn-delete-confirm"
                            onClick={confirmDelete}
                            disabled={deleteCalendar.isPending}
                        >
                            {t('common.delete')}
                        </Button>
                    </DialogFooter>
                </DialogContent>
            </Dialog>

            <EntitySlideOver target={preview} onOpenChange={(open) => !open && setPreview(null)} />
        </>
    );
};

export default CalendarListPage;
