import * as React from 'react';
import AdminLayout from '../layout';
import {
    participantsApi,
    type Participant,
    type ParticipantStatus,
} from '@/features/admin/participants/services/api';
import { Card } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Select } from '@/components/ui/select';
import { DateRangePicker } from '@/components/ui/date-range-picker';
import { ParticipantStatusBadge } from '@/components/ui/status-badge';
import {
    Table,
    TableHead,
    TableBody,
    TableRow,
    TableHeaderCell,
    TableCell,
    TableEmpty,
} from '@/components/ui/table';
import { Pagination } from '@/components/ui/pagination';
import { Spinner } from '@/components/ui/spinner';
import { toast } from '@/components/ui/sonner';
import { formatDate, debounce, downloadBlob } from '@/lib/utils';

const STATUS_OPTIONS = [
    { value: 'in_progress', label: 'In progress' },
    { value: 'completed', label: 'Completed' },
    { value: 'abandoned', label: 'Abandoned' },
    { value: 'unlocked', label: 'Unlocked' },
];

export default function ParticipantsIndex() {
    const [participants, setParticipants] = React.useState<Participant[]>([]);
    const [meta, setMeta] = React.useState({
        page: 1,
        lastPage: 1,
        total: 0,
        perPage: 15,
    });
    const [loading, setLoading] = React.useState(true);
    const [exporting, setExporting] = React.useState(false);

    const [search, setSearch] = React.useState('');
    const [status, setStatus] = React.useState<ParticipantStatus | ''>('');
    const [range, setRange] = React.useState({ from: '', to: '' });

    const filters = React.useMemo(
        () => ({
            search: search || undefined,
            status: (status as ParticipantStatus) || undefined,
            date_from: range.from || undefined,
            date_to: range.to || undefined,
        }),
        [search, status, range.from, range.to],
    );

    const load = React.useCallback(
        (page: number) => {
            setLoading(true);
            participantsApi
                .index({ page, ...filters })
                .then((res) => {
                    setParticipants(res.data || []);
                    setMeta({
                        page: res.meta?.current_page || 1,
                        lastPage: res.meta?.last_page || 1,
                        total: res.meta?.total || 0,
                        perPage: res.meta?.per_page || 15,
                    });
                })
                .catch(() => toast.error('Failed to load participants.'))
                .finally(() => setLoading(false));
            // eslint-disable-next-line react-hooks/exhaustive-deps
        },
        [filters],
    );

    React.useEffect(() => load(1), [load]);

    const debouncedSearch = React.useMemo(
        () => debounce((value: string) => setSearch(value), 300),
        [],
    );

    async function handleExport() {
        setExporting(true);
        try {
            const blob = await participantsApi.export(filters);
            downloadBlob(
                blob,
                `participants-${new Date().toISOString().slice(0, 10)}.xlsx`,
            );
        } catch {
            toast.error('Failed to export participants.');
        } finally {
            setExporting(false);
        }
    }

    return (
        <AdminLayout title="Participants">
            <div className="mb-4 flex flex-wrap items-end justify-between gap-4">
                <div className="flex flex-wrap items-end gap-3">
                    <Input
                        placeholder="Search by name or mobile"
                        className="w-full sm:w-56"
                        aria-label="Search participants"
                        onChange={(e) => debouncedSearch(e.target.value)}
                    />
                    <Select
                        className="w-full sm:w-44"
                        placeholder="All statuses"
                        aria-label="Filter by status"
                        options={STATUS_OPTIONS}
                        value={status}
                        onChange={(e) =>
                            setStatus(e.target.value as ParticipantStatus | '')
                        }
                    />
                    <DateRangePicker
                        from={range.from}
                        to={range.to}
                        onChange={setRange}
                    />
                </div>
                <Button
                    variant="secondary"
                    onClick={handleExport}
                    loading={exporting}
                >
                    Export to Excel
                </Button>
            </div>

            <Card>
                <Table>
                    <TableHead>
                        <tr>
                            <TableHeaderCell>Guest</TableHeaderCell>
                            <TableHeaderCell>Mobile</TableHeaderCell>
                            <TableHeaderCell>Status</TableHeaderCell>
                            <TableHeaderCell>Score</TableHeaderCell>
                            <TableHeaderCell>Offer</TableHeaderCell>
                            <TableHeaderCell>Coupon</TableHeaderCell>
                            <TableHeaderCell>Played at</TableHeaderCell>
                        </tr>
                    </TableHead>
                    <TableBody>
                        {loading ? (
                            <tr>
                                <TableCell colSpan={7}>
                                    <div className="flex justify-center py-10">
                                        <Spinner className="h-5 w-5 text-(--color-accent)" />
                                    </div>
                                </TableCell>
                            </tr>
                        ) : participants.length === 0 ? (
                            <TableEmpty
                                colSpan={7}
                                message="No participants match these filters."
                            />
                        ) : (
                            participants.map((p) => (
                                <TableRow key={p.id}>
                                    <TableCell className="font-medium">
                                        {p.guest.name ?? '—'}
                                    </TableCell>
                                    <TableCell>
                                        {p.guest.mobile ?? '—'}
                                    </TableCell>
                                    <TableCell>
                                        <ParticipantStatusBadge
                                            status={p.status}
                                        />
                                    </TableCell>
                                    <TableCell>{p.score ?? '—'}</TableCell>
                                    <TableCell>
                                        {p.offer?.title ?? '—'}
                                    </TableCell>
                                    <TableCell>
                                        {p.coupon_code ?? '—'}
                                    </TableCell>
                                    <TableCell>
                                        {formatDate(p.played_at)}
                                    </TableCell>
                                </TableRow>
                            ))
                        )}
                    </TableBody>
                </Table>
                <Pagination
                    page={meta.page}
                    lastPage={meta.lastPage}
                    total={meta.total}
                    perPage={meta.perPage}
                    onPageChange={load}
                />
            </Card>
        </AdminLayout>
    );
}
