import { Head, router, useForm } from '@inertiajs/react';
import type { ColumnDef } from '@tanstack/react-table';
import type { FormEvent } from 'react';
import { useMemo, useState } from 'react';
import { DataTable } from '@/components/data-table';
import { FormField } from '@/components/form-field';
import { EmptyState } from '@/components/layout/empty-state';
import { FormDrawer } from '@/components/layout/form-drawer';
import { PageHeader } from '@/components/layout/page-header';
import { SectionCard } from '@/components/layout/section-card';
import { ResourceActionsMenu } from '@/components/resource-actions-menu';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { SheetFooter } from '@/components/ui/sheet';
import { Input } from '@/components/ui/input';
import { NativeSelect } from '@/components/ui/native-select';
import AppLayout from '@/layouts/app-layout';
import adminFleet from '@/routes/admin/fleet';

type VehicleOption = {
    id: number;
    make: string;
    model: string;
    year: number;
    size: string;
};

type FleetAccount = {
    id: number;
    company_name: string;
    contact_name: string;
    contact_email: string;
    contact_phone: string;
    billing_cycle: string;
    discount_percent: number;
    net_days: number;
    fleet_vehicles: Array<{
        id: number;
        vehicle: VehicleOption | null;
    }>;
};

type Props = {
    fleetAccounts: FleetAccount[];
    vehicles: VehicleOption[];
};

export default function AdminFleetIndex({ fleetAccounts, vehicles }: Props) {
    const [editingAccount, setEditingAccount] = useState<FleetAccount | null>(
        null,
    );
    const accountForm = useForm({
        company_name: '',
        contact_name: '',
        contact_email: '',
        contact_phone: '',
        billing_cycle: 'monthly',
        discount_percent: 0,
        net_days: 30,
    });
    const attachForm = useForm({
        fleet_account_id: fleetAccounts[0]?.id ?? 0,
        vehicle_id: vehicles[0]?.id ?? 0,
    });
    const editForm = useForm({
        company_name: '',
        contact_name: '',
        contact_email: '',
        contact_phone: '',
        billing_cycle: 'monthly',
        discount_percent: 0,
        net_days: 30,
    });

    const submitAccount = (event: FormEvent<HTMLFormElement>) => {
        event.preventDefault();
        accountForm.post(adminFleet.accounts.store.url(), {
            onSuccess: () => accountForm.reset(),
        });
    };

    const submitAttach = (event: FormEvent<HTMLFormElement>) => {
        event.preventDefault();

        if (!attachForm.data.fleet_account_id || !attachForm.data.vehicle_id) {
            return;
        }

        attachForm.post(
            adminFleet.accounts.attachVehicle.url({
                fleetAccount: attachForm.data.fleet_account_id,
            }),
        );
    };

    const openEdit = (account: FleetAccount) => {
        setEditingAccount(account);
        editForm.setData({
            company_name: account.company_name,
            contact_name: account.contact_name,
            contact_email: account.contact_email,
            contact_phone: account.contact_phone,
            billing_cycle: account.billing_cycle,
            discount_percent: account.discount_percent,
            net_days: account.net_days,
        });
        editForm.clearErrors();
    };

    const closeEdit = () => {
        setEditingAccount(null);
        editForm.reset();
        editForm.clearErrors();
    };

    const submitEdit = (event: FormEvent<HTMLFormElement>) => {
        event.preventDefault();

        if (!editingAccount) {
            return;
        }

        editForm.patch(
            adminFleet.accounts.update.url({
                fleetAccount: editingAccount.id,
            }),
            {
                onSuccess: () => closeEdit(),
            },
        );
    };

    const deleteAccount = (accountId: number) => {
        router.delete(
            adminFleet.accounts.destroy.url({ fleetAccount: accountId }),
        );
    };

    const detachVehicle = (
        accountId: number,
        fleetAccountVehicleId: number,
    ) => {
        router.delete(
            adminFleet.accounts.detachVehicle.url({
                fleetAccount: accountId,
                fleetAccountVehicle: fleetAccountVehicleId,
            }),
        );
    };

    const columns = useMemo<ColumnDef<FleetAccount>[]>(
        () => [
            {
                accessorKey: 'company_name',
                header: 'Company',
                meta: { label: 'Company' },
                cell: ({ row }) => (
                    <span className="font-medium">
                        {row.getValue('company_name')}
                    </span>
                ),
            },
            {
                accessorKey: 'contact_name',
                header: 'Contact',
                meta: { label: 'Contact' },
            },
            {
                accessorKey: 'contact_email',
                header: 'Email',
                meta: { label: 'Email' },
            },
            {
                accessorKey: 'contact_phone',
                header: 'Phone',
                meta: { label: 'Phone' },
            },
            {
                accessorKey: 'billing_cycle',
                header: 'Billing',
                meta: { label: 'Billing' },
                cell: ({ row }) => (
                    <span className="capitalize">
                        {row.getValue('billing_cycle')}
                    </span>
                ),
            },
            {
                accessorKey: 'discount_percent',
                header: 'Discount',
                meta: { label: 'Discount' },
                cell: ({ row }) => `${row.getValue('discount_percent')}%`,
            },
            {
                accessorKey: 'net_days',
                header: 'Net days',
                meta: { label: 'Net days' },
            },
            {
                id: 'vehicles',
                header: 'Vehicles',
                meta: { label: 'Vehicles' },
                accessorFn: (row) =>
                    row.fleet_vehicles
                        .map((fleetVehicle) =>
                            fleetVehicle.vehicle
                                ? `${fleetVehicle.vehicle.year} ${fleetVehicle.vehicle.make} ${fleetVehicle.vehicle.model}`
                                : 'Unknown vehicle',
                        )
                        .join(', '),
                cell: ({ row }) =>
                    row.original.fleet_vehicles.length === 0 ? (
                        <span className="text-sm text-muted-foreground">
                            None
                        </span>
                    ) : (
                        <div className="flex flex-wrap gap-1.5">
                            {row.original.fleet_vehicles.map((fleetVehicle) => (
                                <Badge key={fleetVehicle.id} variant="secondary">
                                    {fleetVehicle.vehicle
                                        ? `${fleetVehicle.vehicle.year} ${fleetVehicle.vehicle.make} ${fleetVehicle.vehicle.model}`
                                        : 'Unknown vehicle'}
                                </Badge>
                            ))}
                        </div>
                    ),
            },
            {
                id: 'actions',
                enableHiding: false,
                header: () => <span className="sr-only">Actions</span>,
                cell: ({ row }) => (
                    <ResourceActionsMenu
                        onEdit={() => openEdit(row.original)}
                        onDelete={() => deleteAccount(row.original.id)}
                        subMenuLabel="Fleet vehicles"
                        subMenuActions={row.original.fleet_vehicles.map(
                            (fleetVehicle) => ({
                                id: String(fleetVehicle.id),
                                label: fleetVehicle.vehicle
                                    ? `Detach ${fleetVehicle.vehicle.make} ${fleetVehicle.vehicle.model}`
                                    : 'Detach unknown vehicle',
                                onSelect: () =>
                                    detachVehicle(
                                        row.original.id,
                                        fleetVehicle.id,
                                    ),
                                variant: 'destructive' as const,
                            }),
                        )}
                        deleteTitle="Delete fleet account?"
                        deleteDescription="This removes the account and all attached fleet vehicles."
                    />
                ),
            },
        ],
        [],
    );

    return (
        <>
            <Head title="Fleet management" />
            <div className="flex h-full flex-1 flex-col gap-6">
                <PageHeader title="Fleet management" />

                <SectionCard title="Create fleet account">
                    <form
                        onSubmit={submitAccount}
                        className="grid gap-3 md:grid-cols-3"
                    >
                        <FormField label="Company" htmlFor="company_name">
                            <Input
                                id="company_name"
                                value={accountForm.data.company_name}
                                onChange={(event) =>
                                    accountForm.setData(
                                        'company_name',
                                        event.target.value,
                                    )
                                }
                            />
                        </FormField>
                        <FormField label="Contact name" htmlFor="contact_name">
                            <Input
                                id="contact_name"
                                value={accountForm.data.contact_name}
                                onChange={(event) =>
                                    accountForm.setData(
                                        'contact_name',
                                        event.target.value,
                                    )
                                }
                            />
                        </FormField>
                        <FormField label="Contact email" htmlFor="contact_email">
                            <Input
                                id="contact_email"
                                type="email"
                                value={accountForm.data.contact_email}
                                onChange={(event) =>
                                    accountForm.setData(
                                        'contact_email',
                                        event.target.value,
                                    )
                                }
                            />
                        </FormField>
                        <FormField label="Contact phone" htmlFor="contact_phone">
                            <Input
                                id="contact_phone"
                                value={accountForm.data.contact_phone}
                                onChange={(event) =>
                                    accountForm.setData(
                                        'contact_phone',
                                        event.target.value,
                                    )
                                }
                            />
                        </FormField>
                        <FormField label="Billing cycle" htmlFor="billing_cycle">
                            <NativeSelect
                                id="billing_cycle"
                                value={accountForm.data.billing_cycle}
                                onChange={(event) =>
                                    accountForm.setData(
                                        'billing_cycle',
                                        event.target.value,
                                    )
                                }
                            >
                                <option value="monthly">Monthly</option>
                                <option value="weekly">Weekly</option>
                            </NativeSelect>
                        </FormField>
                        <FormField label="Discount %" htmlFor="discount_percent">
                            <Input
                                id="discount_percent"
                                type="number"
                                value={accountForm.data.discount_percent}
                                onChange={(event) =>
                                    accountForm.setData(
                                        'discount_percent',
                                        Number(event.target.value),
                                    )
                                }
                            />
                        </FormField>
                        <FormField label="Net days" htmlFor="net_days">
                            <Input
                                id="net_days"
                                type="number"
                                value={accountForm.data.net_days}
                                onChange={(event) =>
                                    accountForm.setData(
                                        'net_days',
                                        Number(event.target.value),
                                    )
                                }
                            />
                        </FormField>
                        <div className="md:col-span-3">
                            <Button type="submit">Create fleet account</Button>
                        </div>
                    </form>
                </SectionCard>

                <SectionCard title="Attach vehicle to fleet">
                    <form
                        onSubmit={submitAttach}
                        className="grid gap-3 md:grid-cols-3"
                    >
                        <FormField label="Fleet account" htmlFor="fleet_account_id">
                            <NativeSelect
                                id="fleet_account_id"
                                value={attachForm.data.fleet_account_id || ''}
                                onChange={(event) =>
                                    attachForm.setData(
                                        'fleet_account_id',
                                        Number(event.target.value),
                                    )
                                }
                            >
                                {fleetAccounts.map((account) => (
                                    <option key={account.id} value={account.id}>
                                        {account.company_name}
                                    </option>
                                ))}
                            </NativeSelect>
                        </FormField>
                        <FormField label="Vehicle" htmlFor="vehicle_id">
                            <NativeSelect
                                id="vehicle_id"
                                value={attachForm.data.vehicle_id || ''}
                                onChange={(event) =>
                                    attachForm.setData(
                                        'vehicle_id',
                                        Number(event.target.value),
                                    )
                                }
                            >
                                {vehicles.map((vehicle) => (
                                    <option key={vehicle.id} value={vehicle.id}>
                                        {vehicle.year} {vehicle.make}{' '}
                                        {vehicle.model}
                                    </option>
                                ))}
                            </NativeSelect>
                        </FormField>
                        <div className="flex items-end">
                            <Button type="submit">Attach vehicle</Button>
                        </div>
                    </form>
                </SectionCard>

                <SectionCard title="Fleet accounts">
                    {fleetAccounts.length === 0 ? (
                        <EmptyState title="No fleet accounts yet" />
                    ) : (
                        <DataTable
                            columns={columns}
                            data={fleetAccounts}
                            searchPlaceholder="Search fleet accounts..."
                        />
                    )}
                </SectionCard>
            </div>

            <FormDrawer
                open={editingAccount !== null}
                onOpenChange={(open) => {
                    if (!open) {
                        closeEdit();
                    }
                }}
                title="Edit fleet account"
                direction="right"
            >
                <form onSubmit={submitEdit} className="grid gap-3">
                        <FormField label="Company" htmlFor="edit-company">
                            <Input
                                id="edit-company"
                                value={editForm.data.company_name}
                                onChange={(event) =>
                                    editForm.setData(
                                        'company_name',
                                        event.target.value,
                                    )
                                }
                            />
                        </FormField>
                        <FormField
                            label="Contact name"
                            htmlFor="edit-contact-name"
                        >
                            <Input
                                id="edit-contact-name"
                                value={editForm.data.contact_name}
                                onChange={(event) =>
                                    editForm.setData(
                                        'contact_name',
                                        event.target.value,
                                    )
                                }
                            />
                        </FormField>
                        <FormField
                            label="Contact email"
                            htmlFor="edit-contact-email"
                        >
                            <Input
                                id="edit-contact-email"
                                type="email"
                                value={editForm.data.contact_email}
                                onChange={(event) =>
                                    editForm.setData(
                                        'contact_email',
                                        event.target.value,
                                    )
                                }
                            />
                        </FormField>
                        <FormField
                            label="Contact phone"
                            htmlFor="edit-contact-phone"
                        >
                            <Input
                                id="edit-contact-phone"
                                value={editForm.data.contact_phone}
                                onChange={(event) =>
                                    editForm.setData(
                                        'contact_phone',
                                        event.target.value,
                                    )
                                }
                            />
                        </FormField>
                        <FormField
                            label="Billing cycle"
                            htmlFor="edit-billing-cycle"
                        >
                            <NativeSelect
                                id="edit-billing-cycle"
                                value={editForm.data.billing_cycle}
                                onChange={(event) =>
                                    editForm.setData(
                                        'billing_cycle',
                                        event.target.value,
                                    )
                                }
                            >
                                <option value="monthly">Monthly</option>
                                <option value="weekly">Weekly</option>
                            </NativeSelect>
                        </FormField>
                        <FormField
                            label="Discount %"
                            htmlFor="edit-discount-percent"
                        >
                            <Input
                                id="edit-discount-percent"
                                type="number"
                                value={editForm.data.discount_percent}
                                onChange={(event) =>
                                    editForm.setData(
                                        'discount_percent',
                                        Number(event.target.value),
                                    )
                                }
                            />
                        </FormField>
                        <FormField label="Net days" htmlFor="edit-net-days">
                            <Input
                                id="edit-net-days"
                                type="number"
                                value={editForm.data.net_days}
                                onChange={(event) =>
                                    editForm.setData(
                                        'net_days',
                                        Number(event.target.value),
                                    )
                                }
                            />
                        </FormField>
                        <SheetFooter className="px-0 pb-0 sm:flex-row">
                            <Button
                                type="button"
                                variant="outline"
                                onClick={closeEdit}
                            >
                                Cancel
                            </Button>
                            <Button type="submit" disabled={editForm.processing}>
                                Save changes
                            </Button>
                        </SheetFooter>
                    </form>
            </FormDrawer>
        </>
    );
}

AdminFleetIndex.layout = (page: React.ReactNode) => (
    <AppLayout
        breadcrumbs={[
            {
                title: 'Fleet management',
                href: '/admin/fleet',
            },
        ]}
    >
        {page}
    </AppLayout>
);
