import { useForm } from '@inertiajs/react';
import {
    BadgeCheck,
    ClipboardCheck,
    IdCard,
    MapPin,
    ShieldCheck,
    UserRound,
} from 'lucide-react';
import { FormField, NativeSelect } from '@/components/crm/native-select';
import { SectionCard } from '@/components/crm/page-header';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Spinner } from '@/components/ui/spinner';
import { store, update } from '@/routes/installers';
import type { InstallerDetail, InstallerFormOptions } from '@/types';

type InstallerFormData = {
    name: string;
    business_name: string;
    abn: string;
    email: string;
    phone: string;
    address_line1: string;
    address_line2: string;
    suburb: string;
    state: string;
    postcode: string;
    service_area: string;
    electrical_contractor_number: string;
    electrical_contractor_expiry: string;
    electrical_worker_number: string;
    electrical_worker_expiry: string;
    saa_number: string;
    saa_expiry: string;
    cec_number: string;
    accreditation_classes: string[];
    insurance_certificate: string;
    insurance_expiry: string;
    insurance_limit: string;
    professional_indemnity_certificate: string;
    professional_indemnity_expiry: string;
    professional_indemnity_limit: string;
    white_card_number: string;
    working_at_heights_expiry: string;
    arc_tick_licence: string;
    arc_tick_expiry: string;
    forklift_licence: string;
    forklift_expiry: string;
    ewp_licence: string;
    ewp_expiry: string;
    documents_received: boolean;
    is_active: boolean;
    notes: string;
};

/**
 * The installer form, shared by adding and editing.
 *
 * The sections follow what a person checks before sending a crew to a roof: who
 * they are, the electrical licences, the solar accreditation, the insurance, and
 * the site tickets. Every credential keeps the date it runs out, because that
 * date is what decides whether the crew can go.
 */
export function InstallerForm({
    installer,
    options,
}: {
    installer?: InstallerDetail;
    options: InstallerFormOptions;
}) {
    const form = useForm<InstallerFormData>({
        name: installer?.name ?? '',
        business_name: installer?.business_name ?? '',
        abn: installer?.abn ?? '',
        email: installer?.email ?? '',
        phone: installer?.phone ?? '',
        address_line1: installer?.address.line1 ?? '',
        address_line2: installer?.address.line2 ?? '',
        suburb: installer?.address.suburb ?? '',
        state: installer?.address.state ?? '',
        postcode: installer?.address.postcode ?? '',
        service_area: installer?.service_area ?? '',
        electrical_contractor_number:
            installer?.electrical_contractor.number ?? '',
        electrical_contractor_expiry:
            installer?.electrical_contractor.expiry ?? '',
        electrical_worker_number:
            installer?.credentials.find((each) => each.key === 'electrical_worker')
                ?.number ?? '',
        electrical_worker_expiry:
            installer?.credentials.find((each) => each.key === 'electrical_worker')
                ?.expiry ?? '',
        saa_number: installer?.saa.number ?? '',
        saa_expiry: installer?.saa.expiry ?? '',
        cec_number:
            installer?.credentials.find((each) => each.key === 'cec')?.number ??
            '',
        accreditation_classes: installer?.accreditation_classes ?? [],
        insurance_certificate: installer?.insurance.number ?? '',
        insurance_expiry: installer?.insurance.expiry ?? '',
        insurance_limit: installer?.cover.public_liability
            ? String(installer.cover.public_liability)
            : '',
        professional_indemnity_certificate:
            installer?.credentials.find(
                (each) => each.key === 'professional_indemnity',
            )?.number ?? '',
        professional_indemnity_expiry:
            installer?.credentials.find(
                (each) => each.key === 'professional_indemnity',
            )?.expiry ?? '',
        professional_indemnity_limit: installer?.cover.professional_indemnity
            ? String(installer.cover.professional_indemnity)
            : '',
        white_card_number:
            installer?.credentials.find(
                (each) => each.key === 'working_at_heights',
            )?.number ?? '',
        working_at_heights_expiry:
            installer?.credentials.find(
                (each) => each.key === 'working_at_heights',
            )?.expiry ?? '',
        arc_tick_licence:
            installer?.credentials.find((each) => each.key === 'arc_tick')
                ?.number ?? '',
        arc_tick_expiry:
            installer?.credentials.find((each) => each.key === 'arc_tick')
                ?.expiry ?? '',
        forklift_licence:
            installer?.credentials.find((each) => each.key === 'forklift')
                ?.number ?? '',
        forklift_expiry:
            installer?.credentials.find((each) => each.key === 'forklift')
                ?.expiry ?? '',
        ewp_licence:
            installer?.credentials.find((each) => each.key === 'ewp')?.number ??
            '',
        ewp_expiry:
            installer?.credentials.find((each) => each.key === 'ewp')?.expiry ??
            '',
        documents_received: installer?.documents_received ?? false,
        is_active: installer?.is_active ?? true,
        notes: installer?.notes ?? '',
    });

    const error = (field: keyof InstallerFormData) =>
        form.errors[field] as string | undefined;

    const submit = (event: React.FormEvent) => {
        event.preventDefault();

        if (installer) {
            form.put(update(installer.id).url, { preserveScroll: true });

            return;
        }

        form.post(store().url);
    };

    const toggleClass = (value: string, checked: boolean) => {
        const current = form.data.accreditation_classes;

        form.setData(
            'accreditation_classes',
            checked
                ? [...current, value]
                : current.filter((each) => each !== value),
        );
    };

    return (
        <form onSubmit={submit} className="flex flex-col gap-5">
            <SectionCard
                title="Who they are"
                description="The person the office calls and the business that invoices for the work."
                icon={UserRound}
                tone="solar"
            >
                <div className="grid gap-4 sm:grid-cols-2">
                    <FormField
                        label="Name"
                        htmlFor="name"
                        error={error('name')}
                        hint="The person or crew, as you know them."
                        required
                    >
                        <Input
                            id="name"
                            value={form.data.name}
                            onChange={(event) =>
                                form.setData('name', event.target.value)
                            }
                            placeholder="Marc Lemke"
                        />
                    </FormField>

                    <FormField
                        label="Business name"
                        htmlFor="business_name"
                        error={error('business_name')}
                    >
                        <Input
                            id="business_name"
                            value={form.data.business_name}
                            onChange={(event) =>
                                form.setData('business_name', event.target.value)
                            }
                            placeholder="Lemke Electrical"
                        />
                    </FormField>

                    <FormField label="ABN" htmlFor="abn" error={error('abn')}>
                        <Input
                            id="abn"
                            value={form.data.abn}
                            onChange={(event) =>
                                form.setData('abn', event.target.value)
                            }
                            placeholder="12 345 678 901"
                        />
                    </FormField>

                    <FormField
                        label="Service area"
                        htmlFor="service_area"
                        error={error('service_area')}
                        hint="The town or region this crew covers."
                    >
                        <Input
                            id="service_area"
                            value={form.data.service_area}
                            onChange={(event) =>
                                form.setData('service_area', event.target.value)
                            }
                            placeholder="Warrnambool"
                        />
                    </FormField>

                    <FormField
                        label="Email"
                        htmlFor="email"
                        error={error('email')}
                    >
                        <Input
                            id="email"
                            type="email"
                            value={form.data.email}
                            onChange={(event) =>
                                form.setData('email', event.target.value)
                            }
                        />
                    </FormField>

                    <FormField
                        label="Phone"
                        htmlFor="phone"
                        error={error('phone')}
                    >
                        <Input
                            id="phone"
                            value={form.data.phone}
                            onChange={(event) =>
                                form.setData('phone', event.target.value)
                            }
                            placeholder="0400 000 000"
                        />
                    </FormField>
                </div>

                <div className="mt-5 border-t border-hairline pt-4">
                    <p className="mb-3 flex items-center gap-2 text-xs font-medium text-muted-foreground">
                        <MapPin className="size-3.5" />
                        Depot or business address
                    </p>

                    <div className="grid gap-4 sm:grid-cols-2">
                        <FormField
                            label="Street"
                            htmlFor="address_line1"
                            error={error('address_line1')}
                        >
                            <Input
                                id="address_line1"
                                value={form.data.address_line1}
                                onChange={(event) =>
                                    form.setData(
                                        'address_line1',
                                        event.target.value,
                                    )
                                }
                            />
                        </FormField>

                        <FormField
                            label="Suburb"
                            htmlFor="suburb"
                            error={error('suburb')}
                        >
                            <Input
                                id="suburb"
                                value={form.data.suburb}
                                onChange={(event) =>
                                    form.setData('suburb', event.target.value)
                                }
                            />
                        </FormField>

                        <FormField
                            label="State"
                            htmlFor="state"
                            error={error('state')}
                        >
                            <NativeSelect
                                id="state"
                                value={form.data.state}
                                onChange={(event) =>
                                    form.setData('state', event.target.value)
                                }
                            >
                                <option value="">Not recorded</option>
                                {options.states.map((option) => (
                                    <option
                                        key={option.value}
                                        value={option.value}
                                    >
                                        {option.label}
                                    </option>
                                ))}
                            </NativeSelect>
                        </FormField>

                        <FormField
                            label="Postcode"
                            htmlFor="postcode"
                            error={error('postcode')}
                        >
                            <Input
                                id="postcode"
                                value={form.data.postcode}
                                onChange={(event) =>
                                    form.setData('postcode', event.target.value)
                                }
                            />
                        </FormField>
                    </div>
                </div>
            </SectionCard>

            <SectionCard
                title="Electrical licences"
                description="The business licence and the individual electrician's licence are separate credentials, issued by the state regulator."
                icon={IdCard}
                tone="info"
            >
                <div className="grid gap-4 sm:grid-cols-2">
                    <FormField
                        label="Electrical contractor licence"
                        htmlFor="electrical_contractor_number"
                        error={error('electrical_contractor_number')}
                        hint="An REC in Victoria, EC in WA, a contractor licence elsewhere."
                    >
                        <Input
                            id="electrical_contractor_number"
                            value={form.data.electrical_contractor_number}
                            onChange={(event) =>
                                form.setData(
                                    'electrical_contractor_number',
                                    event.target.value,
                                )
                            }
                            placeholder="REC 23526"
                        />
                    </FormField>

                    <FormField
                        label="Contractor licence expiry"
                        htmlFor="electrical_contractor_expiry"
                        error={error('electrical_contractor_expiry')}
                    >
                        <Input
                            id="electrical_contractor_expiry"
                            type="date"
                            value={form.data.electrical_contractor_expiry}
                            onChange={(event) =>
                                form.setData(
                                    'electrical_contractor_expiry',
                                    event.target.value,
                                )
                            }
                        />
                    </FormField>

                    <FormField
                        label="Electrical worker licence"
                        htmlFor="electrical_worker_number"
                        error={error('electrical_worker_number')}
                        hint="The individual electrician's own licence."
                    >
                        <Input
                            id="electrical_worker_number"
                            value={form.data.electrical_worker_number}
                            onChange={(event) =>
                                form.setData(
                                    'electrical_worker_number',
                                    event.target.value,
                                )
                            }
                        />
                    </FormField>

                    <FormField
                        label="Worker licence expiry"
                        htmlFor="electrical_worker_expiry"
                        error={error('electrical_worker_expiry')}
                    >
                        <Input
                            id="electrical_worker_expiry"
                            type="date"
                            value={form.data.electrical_worker_expiry}
                            onChange={(event) =>
                                form.setData(
                                    'electrical_worker_expiry',
                                    event.target.value,
                                )
                            }
                        />
                    </FormField>
                </div>

                <div className="mt-5 border-t border-hairline pt-4">
                    <p className="mb-3 flex items-center gap-2 text-xs font-medium text-muted-foreground">
                        <BadgeCheck className="size-3.5" />
                        Solar Accreditation Australia, which replaced Clean
                        Energy Council accreditation in 2024
                    </p>

                    <div className="grid gap-4 sm:grid-cols-2">
                        <FormField
                            label="SAA accreditation"
                            htmlFor="saa_number"
                            error={error('saa_number')}
                        >
                            <Input
                                id="saa_number"
                                value={form.data.saa_number}
                                onChange={(event) =>
                                    form.setData(
                                        'saa_number',
                                        event.target.value,
                                    )
                                }
                                placeholder="S0773580"
                            />
                        </FormField>

                        <FormField
                            label="SAA expiry"
                            htmlFor="saa_expiry"
                            error={error('saa_expiry')}
                        >
                            <Input
                                id="saa_expiry"
                                type="date"
                                value={form.data.saa_expiry}
                                onChange={(event) =>
                                    form.setData(
                                        'saa_expiry',
                                        event.target.value,
                                    )
                                }
                            />
                        </FormField>

                        <FormField
                            label="CEC number (legacy)"
                            htmlFor="cec_number"
                            error={error('cec_number')}
                            hint="Quoted on job packs from before 2024."
                        >
                            <Input
                                id="cec_number"
                                value={form.data.cec_number}
                                onChange={(event) =>
                                    form.setData(
                                        'cec_number',
                                        event.target.value,
                                    )
                                }
                                placeholder="A3175835"
                            />
                        </FormField>

                        <div className="grid gap-2">
                            <Label>Accreditation classes</Label>
                            <div className="flex flex-wrap gap-4 pt-1">
                                {options.accreditationClasses.map((option) => (
                                    <label
                                        key={option.value}
                                        className="flex items-center gap-2 text-sm"
                                    >
                                        <Checkbox
                                            checked={form.data.accreditation_classes.includes(
                                                option.value,
                                            )}
                                            onCheckedChange={(checked) =>
                                                toggleClass(
                                                    option.value,
                                                    checked === true,
                                                )
                                            }
                                        />
                                        {option.label}
                                    </label>
                                ))}
                            </div>
                            <p className="text-xs text-muted-foreground">
                                GCPV grid-connected PV, GCBS grid-connected
                                battery, SPS standalone power.
                            </p>
                        </div>
                    </div>
                </div>
            </SectionCard>

            <SectionCard
                title="Insurance"
                description="Solar Accreditation Australia asks installers for at least $5m public liability; most principals ask for more."
                icon={ShieldCheck}
                tone="emerald"
            >
                <div className="grid gap-4 sm:grid-cols-3">
                    <FormField
                        label="Certificate of currency"
                        htmlFor="insurance_certificate"
                        error={error('insurance_certificate')}
                    >
                        <Input
                            id="insurance_certificate"
                            value={form.data.insurance_certificate}
                            onChange={(event) =>
                                form.setData(
                                    'insurance_certificate',
                                    event.target.value,
                                )
                            }
                            placeholder="9956768CMB"
                        />
                    </FormField>

                    <FormField
                        label="Expiry"
                        htmlFor="insurance_expiry"
                        error={error('insurance_expiry')}
                    >
                        <Input
                            id="insurance_expiry"
                            type="date"
                            value={form.data.insurance_expiry}
                            onChange={(event) =>
                                form.setData(
                                    'insurance_expiry',
                                    event.target.value,
                                )
                            }
                        />
                    </FormField>

                    <FormField
                        label="Cover (AUD)"
                        htmlFor="insurance_limit"
                        error={error('insurance_limit')}
                    >
                        <Input
                            id="insurance_limit"
                            type="number"
                            min={0}
                            step={1000000}
                            value={form.data.insurance_limit}
                            onChange={(event) =>
                                form.setData(
                                    'insurance_limit',
                                    event.target.value,
                                )
                            }
                            placeholder="20000000"
                        />
                    </FormField>

                    <FormField
                        label="Professional indemnity"
                        htmlFor="professional_indemnity_certificate"
                        error={error('professional_indemnity_certificate')}
                        hint="Required for design-only accreditation."
                    >
                        <Input
                            id="professional_indemnity_certificate"
                            value={form.data.professional_indemnity_certificate}
                            onChange={(event) =>
                                form.setData(
                                    'professional_indemnity_certificate',
                                    event.target.value,
                                )
                            }
                        />
                    </FormField>

                    <FormField
                        label="PI expiry"
                        htmlFor="professional_indemnity_expiry"
                        error={error('professional_indemnity_expiry')}
                    >
                        <Input
                            id="professional_indemnity_expiry"
                            type="date"
                            value={form.data.professional_indemnity_expiry}
                            onChange={(event) =>
                                form.setData(
                                    'professional_indemnity_expiry',
                                    event.target.value,
                                )
                            }
                        />
                    </FormField>

                    <FormField
                        label="PI cover (AUD)"
                        htmlFor="professional_indemnity_limit"
                        error={error('professional_indemnity_limit')}
                    >
                        <Input
                            id="professional_indemnity_limit"
                            type="number"
                            min={0}
                            step={100000}
                            value={form.data.professional_indemnity_limit}
                            onChange={(event) =>
                                form.setData(
                                    'professional_indemnity_limit',
                                    event.target.value,
                                )
                            }
                        />
                    </FormField>
                </div>
            </SectionCard>

            <SectionCard
                title="Site tickets"
                description="What decides whether a crew can be sent to a particular site: induction, heights, refrigerant and heavy equipment."
                icon={ClipboardCheck}
                tone="amber"
            >
                <div className="grid gap-4 sm:grid-cols-2">
                    <FormField
                        label="White card"
                        htmlFor="white_card_number"
                        error={error('white_card_number')}
                        hint="Construction induction card number."
                    >
                        <Input
                            id="white_card_number"
                            value={form.data.white_card_number}
                            onChange={(event) =>
                                form.setData(
                                    'white_card_number',
                                    event.target.value,
                                )
                            }
                        />
                    </FormField>

                    <FormField
                        label="Working at heights expiry"
                        htmlFor="working_at_heights_expiry"
                        error={error('working_at_heights_expiry')}
                    >
                        <Input
                            id="working_at_heights_expiry"
                            type="date"
                            value={form.data.working_at_heights_expiry}
                            onChange={(event) =>
                                form.setData(
                                    'working_at_heights_expiry',
                                    event.target.value,
                                )
                            }
                        />
                    </FormField>

                    <FormField
                        label="ARCtick licence"
                        htmlFor="arc_tick_licence"
                        error={error('arc_tick_licence')}
                        hint="Refrigerant handling, for split-system air conditioning."
                    >
                        <Input
                            id="arc_tick_licence"
                            value={form.data.arc_tick_licence}
                            onChange={(event) =>
                                form.setData(
                                    'arc_tick_licence',
                                    event.target.value,
                                )
                            }
                        />
                    </FormField>

                    <FormField
                        label="ARCtick expiry"
                        htmlFor="arc_tick_expiry"
                        error={error('arc_tick_expiry')}
                    >
                        <Input
                            id="arc_tick_expiry"
                            type="date"
                            value={form.data.arc_tick_expiry}
                            onChange={(event) =>
                                form.setData(
                                    'arc_tick_expiry',
                                    event.target.value,
                                )
                            }
                        />
                    </FormField>

                    <FormField
                        label="Forklift"
                        htmlFor="forklift_licence"
                        error={error('forklift_licence')}
                        hint="The LF licence number, or Yes / No as the register kept it."
                    >
                        <Input
                            id="forklift_licence"
                            value={form.data.forklift_licence}
                            onChange={(event) =>
                                form.setData(
                                    'forklift_licence',
                                    event.target.value,
                                )
                            }
                        />
                    </FormField>

                    <FormField
                        label="Forklift expiry"
                        htmlFor="forklift_expiry"
                        error={error('forklift_expiry')}
                    >
                        <Input
                            id="forklift_expiry"
                            type="date"
                            value={form.data.forklift_expiry}
                            onChange={(event) =>
                                form.setData(
                                    'forklift_expiry',
                                    event.target.value,
                                )
                            }
                        />
                    </FormField>

                    <FormField
                        label="EWP licence"
                        htmlFor="ewp_licence"
                        error={error('ewp_licence')}
                        hint="WP licence, for a boom 11 metres or more."
                    >
                        <Input
                            id="ewp_licence"
                            value={form.data.ewp_licence}
                            onChange={(event) =>
                                form.setData(
                                    'ewp_licence',
                                    event.target.value,
                                )
                            }
                        />
                    </FormField>

                    <FormField
                        label="EWP expiry"
                        htmlFor="ewp_expiry"
                        error={error('ewp_expiry')}
                    >
                        <Input
                            id="ewp_expiry"
                            type="date"
                            value={form.data.ewp_expiry}
                            onChange={(event) =>
                                form.setData(
                                    'ewp_expiry',
                                    event.target.value,
                                )
                            }
                        />
                    </FormField>
                </div>
            </SectionCard>

            <SectionCard
                title="Notes and status"
                icon={ClipboardCheck}
                tone="slate"
            >
                <div className="grid gap-4">
                    <div className="flex flex-wrap gap-6">
                        <label className="flex items-center gap-2 text-sm">
                            <Checkbox
                                checked={form.data.documents_received}
                                onCheckedChange={(checked) =>
                                    form.setData(
                                        'documents_received',
                                        checked === true,
                                    )
                                }
                            />
                            Licence, accreditation and insurance copies on file
                        </label>

                        <label className="flex items-center gap-2 text-sm">
                            <Checkbox
                                checked={form.data.is_active}
                                onCheckedChange={(checked) =>
                                    form.setData(
                                        'is_active',
                                        checked === true,
                                    )
                                }
                            />
                            Still on the register
                        </label>
                    </div>

                    <FormField
                        label="Notes"
                        htmlFor="notes"
                        error={error('notes')}
                        hint="Anything worth knowing before sending them to a customer."
                    >
                        <textarea
                            id="notes"
                            value={form.data.notes}
                            onChange={(event) =>
                                form.setData('notes', event.target.value)
                            }
                            rows={4}
                            className="border-input dark:bg-input/30 focus-visible:border-ring focus-visible:ring-ring/50 flex w-full rounded-md border bg-transparent px-3 py-2 text-sm shadow-xs outline-none focus-visible:ring-[3px]"
                        />
                    </FormField>
                </div>
            </SectionCard>

            <div className="flex items-center gap-2">
                <Button type="submit" disabled={form.processing}>
                    {form.processing && <Spinner />}
                    {installer ? 'Save installer' : 'Add installer'}
                </Button>
                {form.recentlySuccessful ? (
                    <span className="text-xs text-muted-foreground">Saved.</span>
                ) : null}
            </div>
        </form>
    );
}
