import AdminLayout from '@/Layouts/AdminLayout';
import { DataTable, type TableMeta } from '@/components/admin/DataTable';
import PageHeader from '@/components/admin/PageHeader';
import { Button } from '@/components/ui/button';
import {
    DropdownMenu,
    DropdownMenuContent,
    DropdownMenuItem,
    DropdownMenuSeparator,
    DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { useDataTable, type TableParams } from '@/hooks/useDataTable';
import { useDeleteWithUndo } from '@/hooks/useDeleteWithUndo';
import { api } from '@/lib/api';
import { parseServerDate } from '@/lib/date';
import { cn } from '@/lib/utils';
import type { ArticleType } from '@/types/platform';
import { Head, Link, router } from '@inertiajs/react';
import {
    keepPreviousData,
    useQuery,
    useQueryClient,
} from '@tanstack/react-query';
import type { ColumnDef } from '@tanstack/react-table';
import { format } from 'date-fns';
import { Eye, MoreHorizontal, Pencil, Plus, Radio, Trash2 } from 'lucide-react';
import { useState } from 'react';

// ── Types ─────────────────────────────────────────────────────────────────────

interface ArticleRow {
    id: string;
    type: ArticleType;
    title: string;
    body_excerpt: string;
    published_at: string | null;
    status: 'draft' | 'scheduled' | 'published';
    tags: string[];
    created_at: string;
}

interface ArticlesResponse {
    data: ArticleRow[];
    meta: TableMeta;
    filter_counts: Record<string, number>;
}

const TYPE_TABS: { value: ArticleType; label: string }[] = [
    { value: 'news', label: 'News' },
    { value: 'case_study', label: 'Case Studies' },
    { value: 'tutorial', label: 'Tutorials' },
    { value: 'help_article', label: 'Help Articles' },
];

// ── Status badge ──────────────────────────────────────────────────────────────

const STATUS_STYLES = {
    draft: 'bg-muted text-muted-foreground',
    scheduled:
        'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',
    published:
        'bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400',
} as const;

function StatusBadge({ status }: { status: ArticleRow['status'] }) {
    return (
        <span
            className={cn(
                'inline-flex items-center rounded-full px-2 py-0.5 text-[11px] font-medium capitalize',
                STATUS_STYLES[status],
            )}
        >
            {status}
        </span>
    );
}

// ── Quick filters ─────────────────────────────────────────────────────────────

const FILTER_DEFS = [
    { value: 'all', label: 'All' },
    { value: 'published', label: 'Published' },
    { value: 'scheduled', label: 'Scheduled' },
    { value: 'draft', label: 'Draft' },
];

// ── API fetch ─────────────────────────────────────────────────────────────────

function fetchArticles(
    type: ArticleType,
    params: TableParams,
): Promise<ArticlesResponse> {
    const sp = new URLSearchParams({ page: String(params.page), type });
    if (params.filter && params.filter !== 'all')
        sp.set('filter', params.filter);
    if (params.sort) sp.set('sort', params.sort);
    if (params.dir !== 'asc') sp.set('dir', params.dir);
    if (params.search) sp.set('search', params.search);
    return api.get(`/admin/api/articles?${sp}`);
}

// ── Row actions ───────────────────────────────────────────────────────────────

function RowActions({
    row,
    onToggle,
}: {
    row: ArticleRow;
    onToggle: () => void;
}) {
    const handleDelete = () => {
        if (!confirm(`Delete "${row.title}"?`)) return;
        router.delete(`/admin/articles/${row.id}`, { onSuccess: onToggle });
    };

    const handleToggle = () => {
        router.patch(
            `/admin/articles/${row.id}/publish`,
            {},
            { onSuccess: onToggle },
        );
    };

    return (
        <DropdownMenu>
            <DropdownMenuTrigger asChild>
                <button className="text-muted-foreground hover:bg-muted/60 hover:text-foreground flex h-7 w-7 items-center justify-center rounded-md transition-colors focus:outline-none">
                    <MoreHorizontal className="h-4 w-4" />
                    <span className="sr-only">Actions</span>
                </button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end" className="w-44">
                <DropdownMenuItem asChild className="gap-2 text-xs">
                    <Link href={`/admin/articles/${row.id}/edit`}>
                        <Pencil className="h-3.5 w-3.5" />
                        Edit
                    </Link>
                </DropdownMenuItem>
                <DropdownMenuItem
                    className="gap-2 text-xs"
                    onClick={handleToggle}
                >
                    {row.status === 'published' ? (
                        <>
                            <Eye className="h-3.5 w-3.5" />
                            Move to draft
                        </>
                    ) : (
                        <>
                            <Radio className="h-3.5 w-3.5 text-emerald-500" />
                            Publish now
                        </>
                    )}
                </DropdownMenuItem>
                <DropdownMenuSeparator />
                <DropdownMenuItem
                    className="text-destructive focus:text-destructive gap-2 text-xs"
                    onClick={handleDelete}
                >
                    <Trash2 className="h-3.5 w-3.5" />
                    Delete
                </DropdownMenuItem>
            </DropdownMenuContent>
        </DropdownMenu>
    );
}

// ── Column definitions ────────────────────────────────────────────────────────

function buildColumns(
    invalidate: () => void,
): ColumnDef<ArticleRow, unknown>[] {
    return [
        {
            accessorKey: 'title',
            header: 'Title',
            meta: { sortable: true, label: 'Title' },
            cell: ({ row }) => (
                <div className="min-w-0">
                    <Link
                        href={`/admin/articles/${row.original.id}/edit`}
                        className="text-foreground block truncate font-medium hover:opacity-80"
                    >
                        {row.original.title}
                    </Link>
                    <p className="text-muted-foreground mt-0.5 truncate text-[11px]">
                        {row.original.body_excerpt}
                    </p>
                    {row.original.tags.length > 0 && (
                        <div className="mt-1 flex flex-wrap gap-1">
                            {row.original.tags.map((t) => (
                                <span
                                    key={t}
                                    className="bg-muted text-muted-foreground rounded px-1.5 py-0.5 text-[10px]"
                                >
                                    {t}
                                </span>
                            ))}
                        </div>
                    )}
                </div>
            ),
        },
        {
            accessorKey: 'status',
            header: 'Status',
            meta: { sortable: true, label: 'Status' },
            cell: ({ row }) => <StatusBadge status={row.original.status} />,
        },
        {
            accessorKey: 'published_at',
            header: 'Published',
            meta: { sortable: true, label: 'Published' },
            cell: ({ row }) => {
                const d = row.original.published_at;
                return d ? (
                    <span className="text-muted-foreground text-xs tabular-nums">
                        {format(parseServerDate(d), 'dd MMM yyyy')}
                    </span>
                ) : (
                    <span className="text-muted-foreground text-xs">—</span>
                );
            },
        },
        {
            accessorKey: 'created_at',
            header: 'Created',
            meta: { sortable: true, label: 'Created' },
            cell: ({ row }) => (
                <span className="text-muted-foreground text-xs tabular-nums">
                    {format(
                        parseServerDate(row.original.created_at),
                        'dd MMM yyyy',
                    )}
                </span>
            ),
        },
        {
            id: '_actions',
            header: '',
            cell: ({ row }) => (
                <RowActions row={row.original} onToggle={invalidate} />
            ),
            enableHiding: false,
        },
    ];
}

// ── Empty meta ────────────────────────────────────────────────────────────────

const EMPTY_META: TableMeta = {
    current_page: 1,
    last_page: 1,
    total: 0,
    per_page: 25,
    from: 0,
    to: 0,
};

// ── Page ──────────────────────────────────────────────────────────────────────

export default function ArticlesIndex() {
    const [type, setType] = useState<ArticleType>('news');
    const { params, setParams } = useDataTable({
        sort: 'created_at',
        dir: 'desc',
    });
    const queryClient = useQueryClient();

    const { data, isLoading, isFetching } = useQuery({
        queryKey: ['admin.articles', type, params],
        queryFn: () => fetchArticles(type, params),
        placeholderData: keepPreviousData,
    });

    const invalidate = () =>
        queryClient.invalidateQueries({ queryKey: ['admin.articles'] });

    const { deleteWithUndo } = useDeleteWithUndo();
    const handleBulkDelete = (rows: ArticleRow[]) => {
        const ids = rows.map((r) => r.id);
        deleteWithUndo({
            noun: 'article',
            count: ids.length,
            onDelete: () => api.post('/admin/articles/bulk-delete', { ids }),
            onUndo: () => api.post('/admin/articles/bulk-restore', { ids }),
            onSuccess: invalidate,
        });
    };

    const filterCounts = data?.filter_counts ?? {};
    const quickFilters = FILTER_DEFS.map((f) => ({
        ...f,
        count: filterCounts[f.value] ?? 0,
    }));

    const columns = buildColumns(invalidate);

    return (
        <AdminLayout title="Articles">
            <Head title="Articles" />

            <div className="space-y-6 p-6 lg:p-8">
                <PageHeader
                    title="Articles"
                    description="News, case studies, tutorials, and help articles shown on the public site"
                    action={
                        <div className="flex items-center gap-2">
                            <Link
                                href="/admin/articles/trash"
                                className={cn(
                                    'border-border flex items-center gap-1.5 rounded-lg border px-3 py-2',
                                    'text-muted-foreground hover:bg-muted/40 hover:text-foreground text-xs font-medium transition-colors',
                                )}
                            >
                                <Trash2 className="h-3.5 w-3.5" />
                                Trash
                            </Link>
                            <Button asChild size="sm" className="gap-2">
                                <Link href="/admin/articles/create">
                                    <Plus className="h-4 w-4" />
                                    New article
                                </Link>
                            </Button>
                        </div>
                    }
                />

                <Tabs
                    value={type}
                    onValueChange={(v) => setType(v as ArticleType)}
                >
                    <TabsList>
                        {TYPE_TABS.map((t) => (
                            <TabsTrigger key={t.value} value={t.value}>
                                {t.label}
                            </TabsTrigger>
                        ))}
                    </TabsList>
                </Tabs>

                <DataTable
                    columns={columns}
                    data={data?.data ?? []}
                    meta={data?.meta ?? EMPTY_META}
                    params={params}
                    isLoading={isLoading}
                    isFetching={isFetching}
                    onParamsChange={setParams}
                    quickFilters={quickFilters}
                    bulkActions={[
                        {
                            label: 'Delete',
                            icon: Trash2,
                            onClick: handleBulkDelete,
                            variant: 'destructive',
                        },
                    ]}
                    searchPlaceholder="Search articles…"
                    noun="articles"
                    getRowId={(row) => String(row.id)}
                />
            </div>
        </AdminLayout>
    );
}
