import { route } from 'ziggy-js';

import { FormEvent, useMemo, useState } from 'react';

import { Head, Link, router, usePage } from '@inertiajs/react';

import InertiaPagination from '@/Components/Shared/InertiaPagination';
import DashboardLayout from '@/Layouts/DashboardLayout';

interface PostRef {
    id: number | null;
    title: string | null;
    url: string | null;
}

interface Opportunity {
    id: number;
    source: PostRef;
    target: PostRef;
    relevance_score: number;
    suggested_anchor: string;
    target_terms: Array<{ term: string; score: number }>;
    status: 'pending' | 'applied' | 'dismissed';
    applied_at: string | null;
    dismissed_at: string | null;
}

interface PaginatedOpportunities {
    data: Opportunity[];
    links: Array<{ url: string | null; label: string; active: boolean }>;
    current_page: number;
    last_page: number;
    total: number;
}

interface PageProps {
    site: { id: number; name: string; domain: string };
    opportunities: PaginatedOpportunities;
    counts: { pending: number; applied: number; dismissed: number };
    filters: { status: string; min_relevance: number; search: string };
    [key: string]: unknown;
}

type StatusFilter = 'pending' | 'applied' | 'dismissed';

const STATUS_TABS: StatusFilter[] = ['pending', 'applied', 'dismissed'];

export default function LinkOpportunitiesIndex() {
    const { site, opportunities, counts, filters } = usePage<PageProps>().props;
    const [search, setSearch] = useState<string>(filters.search ?? '');
    const [minRelevance, setMinRelevance] = useState<string>(
        filters.min_relevance ? String(filters.min_relevance) : '',
    );

    const hasAny = useMemo(
        () => counts.pending + counts.applied + counts.dismissed > 0,
        [counts],
    );

    const applyFilters = (overrides: Partial<PageProps['filters']> = {}) => {
        router.get(
            route('sites.link-opportunities.index', site.id),
            {
                status: overrides.status ?? filters.status,
                min_relevance: overrides.min_relevance ?? minRelevance,
                search: overrides.search ?? search,
            },
            { preserveState: true, preserveScroll: true, replace: true },
        );
    };

    const onSearchSubmit = (event: FormEvent<HTMLFormElement>) => {
        event.preventDefault();
        applyFilters({ search });
    };

    const onStatusClick = (next: StatusFilter) => {
        applyFilters({ status: next });
    };

    const onUpdateStatus = (opportunity: Opportunity, status: StatusFilter) => {
        router.patch(
            route('sites.link-opportunities.update', [site.id, opportunity.id]),
            { status },
            { preserveScroll: true, preserveState: true },
        );
    };

    const onBuild = () => {
        router.post(
            route('sites.link-opportunities.build', site.id),
            {},
            { preserveScroll: true },
        );
    };

    return (
        <DashboardLayout>
            <Head title="Internal Link Opportunities" />

            <div className="mx-auto max-w-7xl px-4 py-6 sm:px-6 lg:px-8">
                <header className="mb-6 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
                    <div>
                        <h1 className="text-2xl font-semibold text-slate-900 dark:text-slate-100">
                            Internal Link Opportunities
                        </h1>
                        <p className="mt-1 text-sm text-slate-600 dark:text-slate-400">
                            Targeted link suggestions across pages on {site.domain}.
                        </p>
                    </div>
                    <button
                        type="button"
                        onClick={onBuild}
                        className="inline-flex items-center justify-center rounded-md border border-slate-300 bg-white px-3 py-2 text-sm font-medium text-slate-700 shadow-sm hover:bg-slate-50 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:border-slate-600 dark:bg-slate-800 dark:text-slate-100 dark:hover:bg-slate-700"
                    >
                        Re-run analysis
                    </button>
                </header>

                <div className="mb-4 flex flex-wrap gap-2">
                    {STATUS_TABS.map((tab) => {
                        const active = filters.status === tab;
                        return (
                            <button
                                key={tab}
                                type="button"
                                onClick={() => onStatusClick(tab)}
                                className={
                                    'rounded-full border px-3 py-1 text-xs font-medium capitalize transition ' +
                                    (active
                                        ? 'border-indigo-500 bg-indigo-50 text-indigo-700 dark:border-indigo-400 dark:bg-indigo-900/40 dark:text-indigo-200'
                                        : 'border-slate-200 bg-white text-slate-600 hover:bg-slate-50 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-300 dark:hover:bg-slate-700')
                                }
                            >
                                {tab} ({counts[tab]})
                            </button>
                        );
                    })}
                </div>

                <form
                    onSubmit={onSearchSubmit}
                    className="mb-4 grid grid-cols-1 gap-3 sm:grid-cols-[1fr_auto_auto]"
                >
                    <input
                        type="search"
                        value={search}
                        onChange={(e) => setSearch(e.target.value)}
                        placeholder="Search source or target title…"
                        className="rounded-md border border-slate-300 bg-white px-3 py-2 text-sm shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 dark:border-slate-600 dark:bg-slate-800 dark:text-slate-100"
                    />
                    <input
                        type="number"
                        min="0"
                        max="1"
                        step="0.05"
                        value={minRelevance}
                        onChange={(e) => setMinRelevance(e.target.value)}
                        onBlur={() => applyFilters({ min_relevance: Number(minRelevance) || 0 })}
                        placeholder="Min relevance"
                        className="w-40 rounded-md border border-slate-300 bg-white px-3 py-2 text-sm shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 dark:border-slate-600 dark:bg-slate-800 dark:text-slate-100"
                    />
                    <button
                        type="submit"
                        className="rounded-md bg-indigo-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
                    >
                        Search
                    </button>
                </form>

                {!hasAny ? (
                    <div className="rounded-lg border border-dashed border-slate-300 bg-white p-12 text-center dark:border-slate-700 dark:bg-slate-900">
                        <h2 className="text-sm font-semibold text-slate-900 dark:text-slate-100">
                            No link opportunities yet
                        </h2>
                        <p className="mt-1 text-sm text-slate-600 dark:text-slate-400">
                            Run analysis to discover specific internal-link suggestions between pages on this site.
                        </p>
                        <div className="mt-4">
                            <button
                                type="button"
                                onClick={onBuild}
                                className="rounded-md bg-indigo-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-indigo-500"
                            >
                                Run analysis
                            </button>
                        </div>
                    </div>
                ) : (
                    <div className="overflow-hidden rounded-lg border border-slate-200 bg-white shadow-sm dark:border-slate-700 dark:bg-slate-900">
                        <table className="min-w-full divide-y divide-slate-200 dark:divide-slate-700">
                            <thead className="bg-slate-50 dark:bg-slate-800">
                                <tr>
                                    <th className="px-4 py-2 text-left text-xs font-medium uppercase tracking-wider text-slate-500 dark:text-slate-400">
                                        Source
                                    </th>
                                    <th className="px-4 py-2 text-left text-xs font-medium uppercase tracking-wider text-slate-500 dark:text-slate-400">
                                        Target
                                    </th>
                                    <th className="px-4 py-2 text-left text-xs font-medium uppercase tracking-wider text-slate-500 dark:text-slate-400">
                                        Suggested anchor
                                    </th>
                                    <th className="px-4 py-2 text-left text-xs font-medium uppercase tracking-wider text-slate-500 dark:text-slate-400">
                                        Relevance
                                    </th>
                                    <th className="px-4 py-2 text-right text-xs font-medium uppercase tracking-wider text-slate-500 dark:text-slate-400">
                                        Actions
                                    </th>
                                </tr>
                            </thead>
                            <tbody className="divide-y divide-slate-200 dark:divide-slate-700">
                                {opportunities.data.map((opportunity) => (
                                    <tr key={opportunity.id} className="hover:bg-slate-50 dark:hover:bg-slate-800/60">
                                        <td className="px-4 py-3 text-sm text-slate-900 dark:text-slate-100">
                                            {opportunity.source.url ? (
                                                <Link
                                                    href={opportunity.source.url}
                                                    className="hover:underline"
                                                    target="_blank"
                                                    rel="noopener noreferrer"
                                                >
                                                    {opportunity.source.title ?? 'Untitled'}
                                                </Link>
                                            ) : (
                                                <span>{opportunity.source.title ?? 'Untitled'}</span>
                                            )}
                                        </td>
                                        <td className="px-4 py-3 text-sm text-slate-900 dark:text-slate-100">
                                            {opportunity.target.url ? (
                                                <Link
                                                    href={opportunity.target.url}
                                                    className="hover:underline"
                                                    target="_blank"
                                                    rel="noopener noreferrer"
                                                >
                                                    {opportunity.target.title ?? 'Untitled'}
                                                </Link>
                                            ) : (
                                                <span>{opportunity.target.title ?? 'Untitled'}</span>
                                            )}
                                        </td>
                                        <td className="px-4 py-3 font-mono text-sm text-slate-700 dark:text-slate-300">
                                            {opportunity.suggested_anchor}
                                        </td>
                                        <td className="px-4 py-3 text-sm">
                                            <span className="inline-flex items-center rounded-full bg-indigo-50 px-2 py-0.5 text-xs font-medium text-indigo-700 dark:bg-indigo-900/40 dark:text-indigo-200">
                                                {(opportunity.relevance_score * 100).toFixed(0)}%
                                            </span>
                                        </td>
                                        <td className="px-4 py-3 text-right text-sm">
                                            {opportunity.status === 'pending' ? (
                                                <div className="inline-flex gap-2">
                                                    <button
                                                        type="button"
                                                        onClick={() => onUpdateStatus(opportunity, 'applied')}
                                                        className="text-xs font-medium text-indigo-600 hover:underline dark:text-indigo-300"
                                                    >
                                                        Mark applied
                                                    </button>
                                                    <button
                                                        type="button"
                                                        onClick={() => onUpdateStatus(opportunity, 'dismissed')}
                                                        className="text-xs font-medium text-slate-500 hover:underline dark:text-slate-400"
                                                    >
                                                        Dismiss
                                                    </button>
                                                </div>
                                            ) : (
                                                <button
                                                    type="button"
                                                    onClick={() => onUpdateStatus(opportunity, 'pending')}
                                                    className="text-xs font-medium text-slate-500 hover:underline dark:text-slate-400"
                                                >
                                                    Restore
                                                </button>
                                            )}
                                        </td>
                                    </tr>
                                ))}
                                {opportunities.data.length === 0 && (
                                    <tr>
                                        <td
                                            colSpan={5}
                                            className="px-4 py-10 text-center text-sm text-slate-500 dark:text-slate-400"
                                        >
                                            No opportunities match the current filters.
                                        </td>
                                    </tr>
                                )}
                            </tbody>
                        </table>
                        {opportunities.last_page > 1 && (
                            <div className="border-t border-slate-200 px-4 py-3 dark:border-slate-700">
                                <InertiaPagination links={opportunities.links} />
                            </div>
                        )}
                    </div>
                )}
            </div>
        </DashboardLayout>
    );
}
