import { useState } from 'react';
import { Head, Link, router } from '@inertiajs/react';
import { HardHat, Plus, TriangleAlert, Users } from 'lucide-react';
import { NativeSelect } from '@/components/crm/native-select';
import { EmptyState, PageHeader } from '@/components/crm/page-header';
import { StatusPill } from '@/components/crm/status-badge';
import {
    ActiveFilters,
    DataPagination,
    FilterBar,
    FilterField,
    SearchInput,
    TableCard,
} from '@/components/crm/toolbar';
import { Button } from '@/components/ui/button';
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from '@/components/ui/table';
import { formatDate, formatNumber } from '@/lib/format';
import {
    create as installerCreate,
    index as installersIndex,
    show as installerShow,
} from '@/routes/installers';
import type { InstallerSummary, Option, Paginated } from '@/types';

type Filters = {
    search: string | null;
    state: string | null;
    status: string | null;
    compliance: string | null;
};

type PageProps = {
    installers: Paginated<InstallerSummary>;
    filters: Filters;
    filterOptions: {
        states: Option[];
        statuses: Option[];
        compliance: Option[];
    };
    counts: { active: number; expired: number; expiring: number };
    can: { create: boolean; update: boolean; delete: boolean };
};

const statusTone: Record<string, string> = {
    current: 'emerald',
    expiring: 'amber',
    expired: 'red',
    none: 'slate',
};

/**
 * The installer register.
 *
 * It leads with what is about to lapse, because an installer whose electrical
 * contractor licence has expired cannot be booked — the screening is the point
 * of the register, not an extra.
 */
export default function InstallersIndex({
    installers,
    filters,
    filterOptions,
    counts,
    can,
}: PageProps) {
    const [search, setSearch] = useState(filters.search ?? '');

    const navigate = (next: Partial<Filters>) => {
        const merged: Filters = { ...filters, ...next };
        const params: Record<string, string> = {};

        Object.entries(merged).forEach(([key, value]) => {
            if (value !== null && value !== undefined && value !== '') {
                params[key] = String(value);
            }
        });

        router.get(installersIndex().url, params, {
            preserveState: true,
            replace: true,
        });
    };

    const resetAll = () => {
        setSearch('');
        router.get(installersIndex().url);
    };

    const hasFilters =
        Boolean(filters.search) ||
        Boolean(filters.state) ||
        (filters.status ?? 'active') !== 'active' ||
        (filters.compliance ?? 'all') !== 'all';

    type AppliedFilter = {
        key: string;
        label: string;
        value: string;
        onRemove: () => void;
    };

    const filterChips: Array<AppliedFilter | null> = [
        filters.search
            ? {
                  key: 'search',
                  label: 'Search',
                  value: filters.search,
                  onRemove: () => {
                      setSearch('');
                      navigate({ search: null });
                  },
              }
            : null,
        filters.state
            ? {
                  key: 'state',
                  label: 'State',
                  value:
                      filterOptions.states.find(
                          (option) => option.value === filters.state,
                      )?.label ?? filters.state,
                  onRemove: () => navigate({ state: null }),
              }
            : null,
        filters.status && filters.status !== 'active'
            ? {
                  key: 'status',
                  label: 'Status',
                  value:
                      filterOptions.statuses.find(
                          (option) => option.value === filters.status,
                      )?.label ?? filters.status,
                  onRemove: () => navigate({ status: 'active' }),
              }
            : null,
        filters.compliance && filters.compliance !== 'all'
            ? {
                  key: 'compliance',
                  label: 'Credentials',
                  value:
                      filterOptions.compliance.find(
                          (option) => option.value === filters.compliance,
                      )?.label ?? filters.compliance,
                  onRemove: () => navigate({ compliance: 'all' }),
              }
            : null,
    ];

    const appliedFilters = filterChips.filter(
        (filter): filter is AppliedFilter => filter !== null,
    );

    return (
        <>
            <Head title="Installers" />

            <PageHeader
                eyebrow={
                    <>
                        <HardHat className="size-3.5 text-solar" />
                        <span>
                            {formatNumber(counts.active)} in use
                            {counts.expired > 0
                                ? ` · ${formatNumber(counts.expired)} with an expired credential`
                                : ''}
                            {counts.expiring > 0
                                ? ` · ${formatNumber(counts.expiring)} expiring soon`
                                : ''}
                        </span>
                    </>
                }
                title="Installers"
                description="The electrical and solar crews the business sends work to, with the licences, accreditation and insurance that decide whether they can be booked."
                actions={
                    can.create ? (
                        <Button size="sm" asChild>
                            <Link href={installerCreate()}>
                                <Plus />
                                New installer
                            </Link>
                        </Button>
                    ) : null
                }
            />

            {counts.expired > 0 ? (
                <div className="flex items-start gap-3 rounded-xl bg-red-500/10 px-4 py-3 text-sm ring-1 ring-inset ring-red-500/20">
                    <TriangleAlert className="mt-0.5 size-4 shrink-0 text-red-600 dark:text-red-400" />
                    <div>
                        <p className="font-semibold">
                            {formatNumber(counts.expired)} installer
                            {counts.expired === 1 ? ' has' : 's have'} an
                            expired credential
                        </p>
                        <p className="text-muted-foreground mt-0.5 text-xs">
                            They are still on the register, but a lapsed licence
                            or certificate of currency should be renewed before
                            they are booked again.
                        </p>
                    </div>
                    <Button
                        type="button"
                        size="sm"
                        variant="outline"
                        className="ml-auto shrink-0"
                        onClick={() => navigate({ compliance: 'expired' })}
                    >
                        Show them
                    </Button>
                </div>
            ) : null}

            <form
                onSubmit={(event) => {
                    event.preventDefault();
                    navigate({ search: search || null });
                }}
            >
                <FilterBar
                    actions={
                        <>
                            <Button type="submit" size="sm">
                                Apply
                            </Button>
                            {hasFilters ? (
                                <Button
                                    type="button"
                                    variant="ghost"
                                    size="sm"
                                    onClick={resetAll}
                                >
                                    Reset
                                </Button>
                            ) : null}
                        </>
                    }
                >
                    <SearchInput
                        value={search}
                        onChange={setSearch}
                        placeholder="Search name, business, licence, SAA number, email or area"
                    />

                    <FilterField label="State" className="w-32">
                        <NativeSelect
                            className="h-9"
                            value={filters.state ?? ''}
                            onChange={(event) =>
                                navigate({ state: event.target.value || null })
                            }
                            aria-label="Filter by state"
                        >
                            <option value="">All states</option>
                            {filterOptions.states.map((option) => (
                                <option key={option.value} value={option.value}>
                                    {option.value}
                                </option>
                            ))}
                        </NativeSelect>
                    </FilterField>

                    <FilterField label="Register" className="w-40">
                        <NativeSelect
                            className="h-9"
                            value={filters.status ?? 'active'}
                            onChange={(event) =>
                                navigate({ status: event.target.value })
                            }
                            aria-label="Filter by register status"
                        >
                            {filterOptions.statuses.map((option) => (
                                <option key={option.value} value={option.value}>
                                    {option.label}
                                </option>
                            ))}
                        </NativeSelect>
                    </FilterField>

                    <FilterField label="Credentials" className="w-52">
                        <NativeSelect
                            className="h-9"
                            value={filters.compliance ?? 'all'}
                            onChange={(event) =>
                                navigate({ compliance: event.target.value })
                            }
                            aria-label="Filter by credential state"
                        >
                            {filterOptions.compliance.map((option) => (
                                <option key={option.value} value={option.value}>
                                    {option.label}
                                </option>
                            ))}
                        </NativeSelect>
                    </FilterField>
                </FilterBar>
            </form>

            <ActiveFilters filters={[...appliedFilters]} onClear={resetAll} />

            {installers.data.length === 0 ? (
                <EmptyState
                    icon={Users}
                    title="No installers found"
                    description={
                        hasFilters
                            ? 'Try clearing the filters, or search for a name, licence or area.'
                            : 'Add a crew, or import the register from Settings → Sheet import.'
                    }
                    action={
                        can.create ? (
                            <Button asChild size="sm">
                                <Link href={installerCreate()}>
                                    New installer
                                </Link>
                            </Button>
                        ) : null
                    }
                />
            ) : (
                <TableCard>
                    <Table>
                        <TableHeader>
                            <TableRow>
                                <TableHead className="pl-5">Installer</TableHead>
                                <TableHead>Area</TableHead>
                                <TableHead>Contractor licence</TableHead>
                                <TableHead>SAA</TableHead>
                                <TableHead>Insurance</TableHead>
                                <TableHead className="pr-5">Standing</TableHead>
                            </TableRow>
                        </TableHeader>
                        <TableBody>
                            {installers.data.map((installer) => (
                                <TableRow key={installer.id}>
                                    <TableCell className="min-w-56 pl-5">
                                        <Link
                                            href={installerShow(installer.id)}
                                            className="text-sm font-medium hover:underline"
                                        >
                                            {installer.name}
                                        </Link>
                                        <div className="text-muted-foreground mt-0.5 font-mono text-[11px]">
                                            {installer.installer_number}
                                            {installer.business_name
                                                ? ` · ${installer.business_name}`
                                                : ''}
                                        </div>
                                    </TableCell>
                                    <TableCell className="min-w-36 text-sm">
                                        <div>
                                            {installer.state?.value ?? '—'}
                                            {installer.service_area
                                                ? ` · ${installer.service_area}`
                                                : ''}
                                        </div>
                                        <div className="text-muted-foreground mt-0.5 text-xs">
                                            {installer.phone ??
                                                installer.email ??
                                                '—'}
                                        </div>
                                    </TableCell>
                                    <TableCell>
                                        <Credential
                                            number={
                                                installer.electrical_contractor
                                                    .number
                                            }
                                            expiry={
                                                installer.electrical_contractor
                                                    .expiry
                                            }
                                            status={
                                                installer.electrical_contractor
                                                    .status
                                            }
                                        />
                                    </TableCell>
                                    <TableCell>
                                        <Credential
                                            number={installer.saa.number}
                                            expiry={installer.saa.expiry}
                                            status={installer.saa.status}
                                        />
                                    </TableCell>
                                    <TableCell>
                                        <Credential
                                            number={installer.insurance.number}
                                            expiry={installer.insurance.expiry}
                                            status={installer.insurance.status}
                                        />
                                    </TableCell>
                                    <TableCell className="pr-5">
                                        <StatusPill
                                            tone={
                                                statusTone[
                                                    installer.compliance.status
                                                ]
                                            }
                                        >
                                            {installer.compliance.label}
                                        </StatusPill>
                                        {!installer.is_active ? (
                                            <div className="text-muted-foreground mt-1 text-[11px]">
                                                Not used any more
                                            </div>
                                        ) : null}
                                    </TableCell>
                                </TableRow>
                            ))}
                        </TableBody>
                    </Table>

                    <DataPagination page={installers} noun="installers" />
                </TableCard>
            )}
        </>
    );
}

/**
 * One licence in a table cell: the number, then the date it runs out in the
 * colour that date deserves.
 */
function Credential({
    number,
    expiry,
    status,
}: {
    number: string | null;
    expiry: string | null;
    status: string;
}) {
    const tone = {
        current: 'text-foreground',
        expiring: 'text-amber-700 dark:text-amber-300',
        expired: 'text-red-700 dark:text-red-300',
        missing: 'text-muted-foreground',
    }[status];

    return (
        <div>
            <div className="font-mono text-xs">{number ?? '—'}</div>
            <div className={`mt-0.5 text-[11px] ${tone}`}>
                {expiry ? formatDate(expiry) : 'No expiry on file'}
            </div>
        </div>
    );
}

InstallersIndex.layout = {
    breadcrumbs: [{ title: 'Installers', href: installersIndex() }],
};
