import { Head, Link, router, useForm } from '@inertiajs/react';
import {
    BadgeCheck,
    FileSignature,
    Plus,
    Save,
    Send,
    Target,
    TrendingUp,
} from 'lucide-react';
import { useEffect, useState } from 'react';
import { Field } from '@/components/crm/form-field';
import { KpiTile } from '@/components/crm/kpi-tile';
import { NativeSelect } from '@/components/crm/native-select';
import { PageHeader } from '@/components/crm/page-header';
import { StatusLabel } from '@/components/crm/status-badge';
import {
    DataPagination,
    FilterBar,
    FilterField,
    SearchInput,
    SegmentedControl,
    TableCard,
} from '@/components/crm/toolbar';
import { Button } from '@/components/ui/button';
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from '@/components/ui/table';
import {
    formatCompactCurrency,
    formatCurrency,
    formatDate,
} from '@/lib/format';
import { index as leadsIndex } from '@/routes/sales/leads';
import {
    decide,
    index as quotationsIndex,
    store,
} from '@/routes/sales/quotations';
import type { Paginated } from '@/types';

type Option = { value: string; label: string };
type StatusOption = Option & { color: string };

type QuotationRow = {
    id: number;
    quotation_number: string;
    status: StatusOption;
    lead: { id: number; lead_number: string; name: string } | null;
    customer: { id: number; name: string } | null;
    job: { id: number; job_number: string } | null;
    system_summary: string | null;
    system_size_kw: string | null;
    panel_count: number | null;
    panel: string | null;
    inverter: string | null;
    battery: string | null;
    battery_capacity_kwh: string | null;
    total_amount: string | null;
    issued_on: string | null;
    valid_until: string | null;
    decided_on: string | null;
    has_expired: boolean;
};

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

export default function Quotations({
    quotations,
    filters,
    options,
    stats,
    can,
}: {
    quotations: Paginated<QuotationRow>;
    filters: Filters;
    options: {
        quotationStatuses: StatusOption[];
        customers: Array<{ value: number; label: string }>;
        leads: Array<{ value: number; label: string }>;
    };
    stats: {
        live: number;
        live_value: number;
        sent_this_month: number;
        accepted_this_month: number;
        accepted_value: number;
        win_rate: number | null;
    };
    can: { manage: boolean };
}) {
    const [search, setSearch] = useState(filters.search ?? '');
    const [showCreate, setShowCreate] = useState(false);

    useEffect(() => {
        setSearch(filters.search ?? '');
    }, [filters.search]);

    const apply = (changes: Partial<Filters>) => {
        router.get(
            quotationsIndex().url,
            { ...filters, ...changes, search: search || null },
            { preserveState: true, preserveScroll: true, replace: true },
        );
    };

    const decideOn = (quotation: QuotationRow, status: string) => {
        router.post(
            decide(quotation.id).url,
            { status },
            { preserveScroll: true },
        );
    };

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

            <div className="flex flex-col gap-5">
                <PageHeader
                    eyebrow={
                        <>
                            <FileSignature className="size-3.5 text-solar" />
                            <span>Sales</span>
                        </>
                    }
                    title="Quotations"
                    description="What has been offered, at what price, and whether the customer has answered. Accepting a quote wins the lead it came from."
                    actions={
                        <>
                            <Button variant="ghost" size="sm" asChild>
                                <Link href={leadsIndex()}>Leads</Link>
                            </Button>
                            {can.manage ? (
                                <Button
                                    size="sm"
                                    onClick={() => setShowCreate(true)}
                                >
                                    <Plus className="size-4" />
                                    New quotation
                                </Button>
                            ) : null}
                        </>
                    }
                />

                <div className="grid gap-3 sm:grid-cols-2 xl:grid-cols-4">
                    <KpiTile
                        label="Live quotations"
                        value={stats.live}
                        hint="Sent or in progress"
                        icon={Send}
                        tone="violet"
                    />
                    <KpiTile
                        label="Live value"
                        value={formatCompactCurrency(stats.live_value)}
                        hint="Still winnable"
                        icon={TrendingUp}
                        tone="blue"
                    />
                    <KpiTile
                        label="Accepted this month"
                        value={stats.accepted_this_month}
                        hint={formatCompactCurrency(stats.accepted_value)}
                        icon={BadgeCheck}
                        tone="success"
                    />
                    <KpiTile
                        label="Win rate"
                        value={
                            stats.win_rate === null ? '—' : `${stats.win_rate}%`
                        }
                        hint="Accepted against declined"
                        icon={Target}
                        tone="teal"
                    />
                </div>

                <form
                    onSubmit={(event) => {
                        event.preventDefault();
                        apply({});
                    }}
                >
                    <FilterBar
                        actions={
                            <SegmentedControl
                                value={filters.scope}
                                onChange={(scope) => apply({ scope })}
                                options={[
                                    { value: 'live', label: 'Live' },
                                    { value: 'accepted', label: 'Accepted' },
                                    { value: 'all', label: 'All' },
                                ]}
                            />
                        }
                    >
                        <SearchInput
                            value={search}
                            onChange={setSearch}
                            placeholder="Number, customer or reference"
                        />
                        <FilterField label="Status">
                            <NativeSelect
                                value={filters.status ?? ''}
                                onChange={(event) =>
                                    apply({
                                        status: event.target.value || null,
                                    })
                                }
                                className="h-9 w-44"
                            >
                                <option value="">Any status</option>
                                {options.quotationStatuses.map((status) => (
                                    <option
                                        key={status.value}
                                        value={status.value}
                                    >
                                        {status.label}
                                    </option>
                                ))}
                            </NativeSelect>
                        </FilterField>
                    </FilterBar>
                </form>

                <TableCard>
                    <div className="crm-scroll overflow-x-auto">
                        <Table>
                            <TableHeader>
                                <TableRow className="hover:bg-transparent">
                                    <TableHead>Quotation</TableHead>
                                    <TableHead>For</TableHead>
                                    <TableHead>System</TableHead>
                                    <TableHead>Status</TableHead>
                                    <TableHead>Dates</TableHead>
                                    <TableHead className="text-right">
                                        Total
                                    </TableHead>
                                    {can.manage ? <TableHead /> : null}
                                </TableRow>
                            </TableHeader>
                            <TableBody>
                                {quotations.data.length === 0 ? (
                                    <TableRow>
                                        <TableCell
                                            colSpan={can.manage ? 7 : 6}
                                            className="px-4 py-10 text-center text-sm text-muted-foreground"
                                        >
                                            No quotations match these filters.
                                        </TableCell>
                                    </TableRow>
                                ) : null}
                                {quotations.data.map((quotation) => (
                                    <TableRow key={quotation.id}>
                                        <TableCell>
                                            <span className="block font-mono text-xs">
                                                {quotation.quotation_number}
                                            </span>
                                            {quotation.system_summary ? (
                                                <span className="mt-0.5 line-clamp-1 block text-xs text-muted-foreground">
                                                    {quotation.system_summary}
                                                </span>
                                            ) : null}
                                        </TableCell>
                                        <TableCell className="text-sm">
                                            {quotation.lead?.name ??
                                                quotation.customer?.name ??
                                                '—'}
                                            <span className="block text-[11px] text-muted-foreground">
                                                {quotation.lead?.lead_number ??
                                                    quotation.job?.job_number ??
                                                    ''}
                                            </span>
                                        </TableCell>
                                        <TableCell className="text-xs">
                                            {quotation.system_size_kw
                                                ? `${Number(
                                                      quotation.system_size_kw,
                                                  )} kW`
                                                : '—'}
                                            {quotation.panel ? (
                                                <span className="block text-muted-foreground">
                                                    {quotation.panel_count ?? 0}{' '}
                                                    × {quotation.panel}
                                                </span>
                                            ) : null}
                                            {quotation.battery ? (
                                                <span className="block text-muted-foreground">
                                                    {quotation.battery}{' '}
                                                    {quotation.battery_capacity_kwh
                                                        ? `${Number(
                                                              quotation.battery_capacity_kwh,
                                                          )} kWh`
                                                        : ''}
                                                </span>
                                            ) : null}
                                        </TableCell>
                                        <TableCell>
                                            <StatusLabel
                                                tone={quotation.status.color}
                                            >
                                                {quotation.status.label}
                                            </StatusLabel>
                                        </TableCell>
                                        <TableCell className="text-xs text-muted-foreground">
                                            <span className="block">
                                                Issued{' '}
                                                {formatDate(
                                                    quotation.issued_on,
                                                )}
                                            </span>
                                            {quotation.valid_until ? (
                                                <span
                                                    className={
                                                        quotation.has_expired
                                                            ? 'block text-destructive'
                                                            : 'block'
                                                    }
                                                >
                                                    Valid to{' '}
                                                    {formatDate(
                                                        quotation.valid_until,
                                                    )}
                                                </span>
                                            ) : null}
                                        </TableCell>
                                        <TableCell className="text-right text-sm crm-num">
                                            {formatCurrency(
                                                quotation.total_amount === null
                                                    ? null
                                                    : Number(
                                                          quotation.total_amount,
                                                      ),
                                            )}
                                        </TableCell>
                                        {can.manage ? (
                                            <TableCell className="text-right">
                                                {quotation.status.value ===
                                                    'sent' ||
                                                quotation.status.value ===
                                                    'awaiting_approval' ? (
                                                    <div className="flex justify-end gap-1">
                                                        <Button
                                                            size="sm"
                                                            variant="ghost"
                                                            onClick={() =>
                                                                decideOn(
                                                                    quotation,
                                                                    'accepted',
                                                                )
                                                            }
                                                        >
                                                            Accept
                                                        </Button>
                                                        <Button
                                                            size="sm"
                                                            variant="ghost"
                                                            onClick={() =>
                                                                decideOn(
                                                                    quotation,
                                                                    'declined',
                                                                )
                                                            }
                                                        >
                                                            Decline
                                                        </Button>
                                                    </div>
                                                ) : null}
                                            </TableCell>
                                        ) : null}
                                    </TableRow>
                                ))}
                            </TableBody>
                        </Table>
                    </div>
                    <DataPagination page={quotations} noun="quotations" />
                </TableCard>
            </div>

            {can.manage ? (
                <QuotationDialog
                    open={showCreate}
                    options={options}
                    onClose={() => setShowCreate(false)}
                />
            ) : null}
        </>
    );
}

function QuotationDialog({
    open,
    options,
    onClose,
}: {
    open: boolean;
    options: {
        customers: Array<{ value: number; label: string }>;
        leads: Array<{ value: number; label: string }>;
    };
    onClose: () => void;
}) {
    const form = useForm({
        lead_id: '',
        customer_id: '',
        status: 'draft',
        valid_until: '',
        system_summary: '',
        system_size_kw: '',
        panel_count: '',
        panel_make: '',
        panel_model: '',
        inverter_make: '',
        inverter_model: '',
        battery_make: '',
        battery_model: '',
        battery_capacity_kwh: '',
        total_amount: '',
        reference: '',
        notes: '',
    });

    const submit = () => {
        form.post(store().url, {
            preserveScroll: true,
            onSuccess: () => {
                form.reset();
                onClose();
            },
        });
    };

    return (
        <Dialog open={open} onOpenChange={(state) => !state && onClose()}>
            <DialogContent className="max-h-[90vh] overflow-y-auto sm:max-w-2xl">
                <DialogHeader>
                    <DialogTitle>New quotation</DialogTitle>
                    <DialogDescription>
                        Attach it to a lead or an existing customer. The system
                        details are what the install is handed over with.
                    </DialogDescription>
                </DialogHeader>

                <form
                    onSubmit={(event) => {
                        event.preventDefault();
                        submit();
                    }}
                    className="grid gap-3 sm:grid-cols-2"
                >
                    <Field label="Lead" error={form.errors.lead_id}>
                        <NativeSelect
                            value={form.data.lead_id}
                            onChange={(event) => {
                                form.setData('lead_id', event.target.value);
                                // One owner only: quoting an existing customer
                                // should not leave a lead attached as well.
                                if (event.target.value) {
                                    form.setData('customer_id', '');
                                }
                            }}
                        >
                            <option value="">No lead</option>
                            {options.leads.map((lead) => (
                                <option key={lead.value} value={lead.value}>
                                    {lead.label}
                                </option>
                            ))}
                        </NativeSelect>
                    </Field>
                    <Field label="Customer" error={form.errors.customer_id}>
                        <NativeSelect
                            value={form.data.customer_id}
                            onChange={(event) => {
                                form.setData('customer_id', event.target.value);
                                if (event.target.value) {
                                    form.setData('lead_id', '');
                                }
                            }}
                        >
                            <option value="">No customer</option>
                            {options.customers.map((customer) => (
                                <option
                                    key={customer.value}
                                    value={customer.value}
                                >
                                    {customer.label}
                                </option>
                            ))}
                        </NativeSelect>
                    </Field>
                    <Field label="Status" error={form.errors.status}>
                        <NativeSelect
                            value={form.data.status}
                            onChange={(event) =>
                                form.setData('status', event.target.value)
                            }
                        >
                            <option value="draft">Draft</option>
                            <option value="sent">Sent</option>
                            <option value="awaiting_approval">
                                Awaiting approval
                            </option>
                        </NativeSelect>
                    </Field>
                    <Field label="Valid until" error={form.errors.valid_until}>
                        <Input
                            type="date"
                            value={form.data.valid_until}
                            onChange={(event) =>
                                form.setData('valid_until', event.target.value)
                            }
                        />
                    </Field>
                    <Field
                        label="Total (inc GST)"
                        error={form.errors.total_amount}
                    >
                        <Input
                            type="number"
                            min={0}
                            step="0.01"
                            value={form.data.total_amount}
                            onChange={(event) =>
                                form.setData('total_amount', event.target.value)
                            }
                        />
                    </Field>
                    <Field
                        label="System size (kW)"
                        error={form.errors.system_size_kw}
                    >
                        <Input
                            type="number"
                            min={0}
                            step="0.01"
                            value={form.data.system_size_kw}
                            onChange={(event) =>
                                form.setData(
                                    'system_size_kw',
                                    event.target.value,
                                )
                            }
                        />
                    </Field>
                    <Field label="Panels" error={form.errors.panel_count}>
                        <div className="grid grid-cols-3 gap-2">
                            <Input
                                type="number"
                                min={0}
                                value={form.data.panel_count}
                                onChange={(event) =>
                                    form.setData(
                                        'panel_count',
                                        event.target.value,
                                    )
                                }
                            />
                            <Input
                                className="col-span-2"
                                placeholder="Make and model"
                                value={form.data.panel_model}
                                onChange={(event) => {
                                    form.setData(
                                        'panel_model',
                                        event.target.value,
                                    );
                                }}
                            />
                        </div>
                    </Field>
                    <Field label="Inverter" error={form.errors.inverter_make}>
                        <Input
                            placeholder="Make and model"
                            value={form.data.inverter_model}
                            onChange={(event) =>
                                form.setData(
                                    'inverter_model',
                                    event.target.value,
                                )
                            }
                        />
                    </Field>
                    <Field label="Battery" error={form.errors.battery_make}>
                        <Input
                            placeholder="Make and model"
                            value={form.data.battery_model}
                            onChange={(event) =>
                                form.setData(
                                    'battery_model',
                                    event.target.value,
                                )
                            }
                        />
                    </Field>
                    <Field
                        label="Battery size (kWh)"
                        error={form.errors.battery_capacity_kwh}
                    >
                        <Input
                            type="number"
                            min={0}
                            step="0.01"
                            value={form.data.battery_capacity_kwh}
                            onChange={(event) =>
                                form.setData(
                                    'battery_capacity_kwh',
                                    event.target.value,
                                )
                            }
                        />
                    </Field>
                    <Field
                        label="System summary"
                        error={form.errors.system_summary}
                        className="sm:col-span-2"
                    >
                        <textarea
                            rows={3}
                            value={form.data.system_summary}
                            onChange={(event) =>
                                form.setData(
                                    'system_summary',
                                    event.target.value,
                                )
                            }
                            className="w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"
                        />
                    </Field>

                    <DialogFooter className="sm:col-span-2">
                        <Button type="button" variant="ghost" onClick={onClose}>
                            Cancel
                        </Button>
                        <Button type="submit" disabled={form.processing}>
                            <Save className="size-4" />
                            Create quotation
                        </Button>
                    </DialogFooter>
                </form>
            </DialogContent>
        </Dialog>
    );
}
