import { Head, Link, useForm } from '@inertiajs/react';
import { Plus, Trash2 } from 'lucide-react';
import { ConflictCheckWidget } from '@/components/conflict-check-widget';
import InputError from '@/components/input-error';
import { PageHeader } from '@/components/page-header';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import { Spinner } from '@/components/ui/spinner';
import { Textarea } from '@/components/ui/textarea';
import { index, show, store, update } from '@/routes/matters';

type Option = { value: number | string; label: string };

type Options = {
    matterTypes: Option[];
    priorities: Option[];
    partyRoles: Option[];
    teamRoles: Option[];
    clients: Option[];
    practiceAreas: Option[];
    courts: Option[];
    stages: Option[];
    offices: Option[];
    users: Option[];
};

type Matter = {
    id: string;
    title: string;
    matter_type: string;
    client_id: number;
    client_name: string;
    practice_area_id: number | null;
    court_id: number | null;
    office_id: number | null;
    responsible_partner_id: number | null;
    client_role: string | null;
    priority: string;
    date_opened: string | null;
    filing_date: string | null;
    suit_number: string | null;
    summary: string | null;
    relief_sought: string | null;
    opposing_counsel: string | null;
    claim_amount: string | null;
    estimated_value: string | null;
};

type TeamRow = { user_id: number | null; role: string };
type PartyRow = {
    name: string;
    role: string;
    phone: string;
    address: string;
    notes: string;
};

const NONE = 'none';

export default function MatterForm({
    matter,
    options,
}: {
    matter: Matter | null;
    options: Options;
}) {
    const editing = matter !== null;

    const form = useForm({
        title: matter?.title ?? '',
        matter_type: matter?.matter_type ?? 'litigation',
        client_id: matter?.client_id ?? (null as number | null),
        practice_area_id: matter?.practice_area_id ?? null,
        court_id: matter?.court_id ?? null,
        office_id: matter?.office_id ?? null,
        responsible_partner_id: matter?.responsible_partner_id ?? null,
        client_role: matter?.client_role ?? null,
        priority: matter?.priority ?? 'normal',
        date_opened:
            matter?.date_opened ?? new Date().toISOString().slice(0, 10),
        filing_date: matter?.filing_date ?? '',
        suit_number: matter?.suit_number ?? '',
        summary: matter?.summary ?? '',
        relief_sought: matter?.relief_sought ?? '',
        opposing_counsel: matter?.opposing_counsel ?? '',
        claim_amount: matter?.claim_amount ?? '',
        estimated_value: matter?.estimated_value ?? '',
        team: [{ user_id: null, role: 'lead_counsel' }] as TeamRow[],
        parties: [] as PartyRow[],
    });

    const isLitigation = form.data.matter_type === 'litigation';

    const setTeam = (rows: TeamRow[]) => form.setData('team', rows);
    const setParties = (rows: PartyRow[]) => form.setData('parties', rows);

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

        if (editing) {
            form.transform((d) => {
                const { team: _t, parties: _p, client_id: _c, ...core } = d;
                void _t;
                void _p;
                void _c;

                return core;
            });
            form.put(update(matter.id).url, { preserveScroll: true });
        } else {
            form.transform((d) => d);
            form.post(store().url, { preserveScroll: true });
        }
    };

    const num = (v: string) => (v === NONE ? null : Number(v));

    return (
        <>
            <Head title={editing ? 'Edit matter' : 'New matter'} />
            <form onSubmit={submit} className="flex flex-col gap-6 p-4">
                <PageHeader
                    title={editing ? 'Edit matter' : 'Register a matter'}
                    subtitle={
                        editing
                            ? matter!.title
                            : 'Open a new litigation or advisory matter.'
                    }
                    action={
                        <div className="flex gap-2">
                            <Button asChild variant="outline" type="button">
                                <Link
                                    href={editing ? show(matter!.id) : index()}
                                >
                                    Cancel
                                </Link>
                            </Button>
                            <Button type="submit" disabled={form.processing}>
                                {form.processing && <Spinner />}
                                {editing ? 'Save' : 'Register matter'}
                            </Button>
                        </div>
                    }
                />

                <div className="grid gap-6 lg:grid-cols-3">
                    <div className="flex flex-col gap-6 lg:col-span-2">
                        <Card>
                            <CardHeader>
                                <CardTitle>Matter details</CardTitle>
                            </CardHeader>
                            <CardContent className="grid gap-4 sm:grid-cols-2">
                                <div className="grid gap-2 sm:col-span-2">
                                    <Label htmlFor="title">Title</Label>
                                    <Input
                                        id="title"
                                        value={form.data.title}
                                        onChange={(e) =>
                                            form.setData(
                                                'title',
                                                e.target.value,
                                            )
                                        }
                                        required
                                    />
                                    <InputError message={form.errors.title} />
                                </div>
                                <div className="grid gap-2">
                                    <Label htmlFor="matter_type">Type</Label>
                                    <Select
                                        value={form.data.matter_type}
                                        onValueChange={(v) =>
                                            form.setData('matter_type', v)
                                        }
                                    >
                                        <SelectTrigger id="matter_type">
                                            <SelectValue />
                                        </SelectTrigger>
                                        <SelectContent>
                                            {options.matterTypes.map((o) => (
                                                <SelectItem
                                                    key={o.value}
                                                    value={String(o.value)}
                                                >
                                                    {o.label}
                                                </SelectItem>
                                            ))}
                                        </SelectContent>
                                    </Select>
                                    <InputError
                                        message={form.errors.matter_type}
                                    />
                                </div>
                                <div className="grid gap-2">
                                    <Label htmlFor="priority">Priority</Label>
                                    <Select
                                        value={form.data.priority}
                                        onValueChange={(v) =>
                                            form.setData('priority', v)
                                        }
                                    >
                                        <SelectTrigger id="priority">
                                            <SelectValue />
                                        </SelectTrigger>
                                        <SelectContent>
                                            {options.priorities.map((o) => (
                                                <SelectItem
                                                    key={o.value}
                                                    value={String(o.value)}
                                                >
                                                    {o.label}
                                                </SelectItem>
                                            ))}
                                        </SelectContent>
                                    </Select>
                                </div>
                                {!editing && (
                                    <div className="grid gap-2 sm:col-span-2">
                                        <Label htmlFor="client_id">
                                            Client
                                        </Label>
                                        <Select
                                            value={
                                                form.data.client_id
                                                    ? String(
                                                          form.data.client_id,
                                                      )
                                                    : ''
                                            }
                                            onValueChange={(v) =>
                                                form.setData(
                                                    'client_id',
                                                    Number(v),
                                                )
                                            }
                                        >
                                            <SelectTrigger id="client_id">
                                                <SelectValue placeholder="Select a client" />
                                            </SelectTrigger>
                                            <SelectContent>
                                                {options.clients.map((o) => (
                                                    <SelectItem
                                                        key={o.value}
                                                        value={String(o.value)}
                                                    >
                                                        {o.label}
                                                    </SelectItem>
                                                ))}
                                            </SelectContent>
                                        </Select>
                                        <InputError
                                            message={form.errors.client_id}
                                        />
                                    </div>
                                )}
                                {editing && (
                                    <div className="grid gap-2 sm:col-span-2">
                                        <Label>Client</Label>
                                        <Input
                                            value={matter!.client_name}
                                            disabled
                                        />
                                    </div>
                                )}
                                <div className="grid gap-2">
                                    <Label htmlFor="practice_area_id">
                                        Practice area
                                    </Label>
                                    <Select
                                        value={
                                            form.data.practice_area_id
                                                ? String(
                                                      form.data
                                                          .practice_area_id,
                                                  )
                                                : NONE
                                        }
                                        onValueChange={(v) =>
                                            form.setData(
                                                'practice_area_id',
                                                num(v),
                                            )
                                        }
                                    >
                                        <SelectTrigger id="practice_area_id">
                                            <SelectValue placeholder="None" />
                                        </SelectTrigger>
                                        <SelectContent>
                                            <SelectItem value={NONE}>
                                                None
                                            </SelectItem>
                                            {options.practiceAreas.map((o) => (
                                                <SelectItem
                                                    key={o.value}
                                                    value={String(o.value)}
                                                >
                                                    {o.label}
                                                </SelectItem>
                                            ))}
                                        </SelectContent>
                                    </Select>
                                </div>
                                <div className="grid gap-2">
                                    <Label htmlFor="responsible_partner_id">
                                        Responsible partner
                                    </Label>
                                    <Select
                                        value={
                                            form.data.responsible_partner_id
                                                ? String(
                                                      form.data
                                                          .responsible_partner_id,
                                                  )
                                                : NONE
                                        }
                                        onValueChange={(v) =>
                                            form.setData(
                                                'responsible_partner_id',
                                                num(v),
                                            )
                                        }
                                    >
                                        <SelectTrigger id="responsible_partner_id">
                                            <SelectValue placeholder="Unassigned" />
                                        </SelectTrigger>
                                        <SelectContent>
                                            <SelectItem value={NONE}>
                                                Unassigned
                                            </SelectItem>
                                            {options.users.map((o) => (
                                                <SelectItem
                                                    key={o.value}
                                                    value={String(o.value)}
                                                >
                                                    {o.label}
                                                </SelectItem>
                                            ))}
                                        </SelectContent>
                                    </Select>
                                </div>
                                <div className="grid gap-2">
                                    <Label htmlFor="office_id">Office</Label>
                                    <Select
                                        value={
                                            form.data.office_id
                                                ? String(form.data.office_id)
                                                : NONE
                                        }
                                        onValueChange={(v) =>
                                            form.setData('office_id', num(v))
                                        }
                                    >
                                        <SelectTrigger id="office_id">
                                            <SelectValue placeholder="None" />
                                        </SelectTrigger>
                                        <SelectContent>
                                            <SelectItem value={NONE}>
                                                None
                                            </SelectItem>
                                            {options.offices.map((o) => (
                                                <SelectItem
                                                    key={o.value}
                                                    value={String(o.value)}
                                                >
                                                    {o.label}
                                                </SelectItem>
                                            ))}
                                        </SelectContent>
                                    </Select>
                                </div>
                                <div className="grid gap-2">
                                    <Label htmlFor="date_opened">
                                        Date opened
                                    </Label>
                                    <Input
                                        id="date_opened"
                                        type="date"
                                        value={form.data.date_opened}
                                        onChange={(e) =>
                                            form.setData(
                                                'date_opened',
                                                e.target.value,
                                            )
                                        }
                                        required
                                    />
                                    <InputError
                                        message={form.errors.date_opened}
                                    />
                                </div>
                                <div className="grid gap-2 sm:col-span-2">
                                    <Label htmlFor="summary">Summary</Label>
                                    <Textarea
                                        id="summary"
                                        value={form.data.summary}
                                        onChange={(e) =>
                                            form.setData(
                                                'summary',
                                                e.target.value,
                                            )
                                        }
                                    />
                                </div>
                            </CardContent>
                        </Card>

                        <Card>
                            <CardHeader>
                                <CardTitle>
                                    {isLitigation
                                        ? 'Litigation details'
                                        : 'Matter value'}
                                </CardTitle>
                            </CardHeader>
                            <CardContent className="grid gap-4 sm:grid-cols-2">
                                {isLitigation ? (
                                    <>
                                        <div className="grid gap-2">
                                            <Label htmlFor="suit_number">
                                                Suit number
                                            </Label>
                                            <Input
                                                id="suit_number"
                                                value={form.data.suit_number}
                                                onChange={(e) =>
                                                    form.setData(
                                                        'suit_number',
                                                        e.target.value,
                                                    )
                                                }
                                            />
                                        </div>
                                        <div className="grid gap-2">
                                            <Label htmlFor="court_id">
                                                Court
                                            </Label>
                                            <Select
                                                value={
                                                    form.data.court_id
                                                        ? String(
                                                              form.data
                                                                  .court_id,
                                                          )
                                                        : NONE
                                                }
                                                onValueChange={(v) =>
                                                    form.setData(
                                                        'court_id',
                                                        num(v),
                                                    )
                                                }
                                            >
                                                <SelectTrigger id="court_id">
                                                    <SelectValue placeholder="None" />
                                                </SelectTrigger>
                                                <SelectContent>
                                                    <SelectItem value={NONE}>
                                                        None
                                                    </SelectItem>
                                                    {options.courts.map((o) => (
                                                        <SelectItem
                                                            key={o.value}
                                                            value={String(
                                                                o.value,
                                                            )}
                                                        >
                                                            {o.label}
                                                        </SelectItem>
                                                    ))}
                                                </SelectContent>
                                            </Select>
                                        </div>
                                        <div className="grid gap-2">
                                            <Label htmlFor="client_role">
                                                Client's role
                                            </Label>
                                            <Select
                                                value={
                                                    form.data.client_role ??
                                                    NONE
                                                }
                                                onValueChange={(v) =>
                                                    form.setData(
                                                        'client_role',
                                                        v === NONE ? null : v,
                                                    )
                                                }
                                            >
                                                <SelectTrigger id="client_role">
                                                    <SelectValue placeholder="None" />
                                                </SelectTrigger>
                                                <SelectContent>
                                                    <SelectItem value={NONE}>
                                                        None
                                                    </SelectItem>
                                                    {options.partyRoles.map(
                                                        (o) => (
                                                            <SelectItem
                                                                key={o.value}
                                                                value={String(
                                                                    o.value,
                                                                )}
                                                            >
                                                                {o.label}
                                                            </SelectItem>
                                                        ),
                                                    )}
                                                </SelectContent>
                                            </Select>
                                        </div>
                                        <div className="grid gap-2">
                                            <Label htmlFor="opposing_counsel">
                                                Opposing counsel
                                            </Label>
                                            <Input
                                                id="opposing_counsel"
                                                value={
                                                    form.data.opposing_counsel
                                                }
                                                onChange={(e) =>
                                                    form.setData(
                                                        'opposing_counsel',
                                                        e.target.value,
                                                    )
                                                }
                                            />
                                        </div>
                                        <div className="grid gap-2">
                                            <Label htmlFor="claim_amount">
                                                Claim amount (₦)
                                            </Label>
                                            <Input
                                                id="claim_amount"
                                                inputMode="decimal"
                                                value={form.data.claim_amount}
                                                onChange={(e) =>
                                                    form.setData(
                                                        'claim_amount',
                                                        e.target.value,
                                                    )
                                                }
                                            />
                                        </div>
                                        <div className="grid gap-2 sm:col-span-2">
                                            <Label htmlFor="relief_sought">
                                                Relief sought
                                            </Label>
                                            <Textarea
                                                id="relief_sought"
                                                value={form.data.relief_sought}
                                                onChange={(e) =>
                                                    form.setData(
                                                        'relief_sought',
                                                        e.target.value,
                                                    )
                                                }
                                            />
                                        </div>
                                    </>
                                ) : (
                                    <div className="grid gap-2">
                                        <Label htmlFor="estimated_value">
                                            Estimated value (₦)
                                        </Label>
                                        <Input
                                            id="estimated_value"
                                            inputMode="decimal"
                                            value={form.data.estimated_value}
                                            onChange={(e) =>
                                                form.setData(
                                                    'estimated_value',
                                                    e.target.value,
                                                )
                                            }
                                        />
                                    </div>
                                )}
                            </CardContent>
                        </Card>

                        {!editing && (
                            <>
                                <Card>
                                    <CardHeader>
                                        <CardTitle>Team</CardTitle>
                                    </CardHeader>
                                    <CardContent className="space-y-3">
                                        {form.data.team.map((row, i) => (
                                            <div
                                                key={i}
                                                className="flex flex-wrap items-end gap-2"
                                            >
                                                <div className="grid flex-1 gap-2">
                                                    <Label>
                                                        Member{' '}
                                                        {i === 0
                                                            ? '(lead)'
                                                            : ''}
                                                    </Label>
                                                    <Select
                                                        value={
                                                            row.user_id
                                                                ? String(
                                                                      row.user_id,
                                                                  )
                                                                : ''
                                                        }
                                                        onValueChange={(v) => {
                                                            const next = [
                                                                ...form.data
                                                                    .team,
                                                            ];
                                                            next[i] = {
                                                                ...row,
                                                                user_id:
                                                                    Number(v),
                                                            };
                                                            setTeam(next);
                                                        }}
                                                    >
                                                        <SelectTrigger>
                                                            <SelectValue placeholder="Select a person" />
                                                        </SelectTrigger>
                                                        <SelectContent>
                                                            {options.users.map(
                                                                (o) => (
                                                                    <SelectItem
                                                                        key={
                                                                            o.value
                                                                        }
                                                                        value={String(
                                                                            o.value,
                                                                        )}
                                                                    >
                                                                        {
                                                                            o.label
                                                                        }
                                                                    </SelectItem>
                                                                ),
                                                            )}
                                                        </SelectContent>
                                                    </Select>
                                                </div>
                                                <div className="grid w-40 gap-2">
                                                    <Label>Role</Label>
                                                    <Select
                                                        value={row.role}
                                                        onValueChange={(v) => {
                                                            const next = [
                                                                ...form.data
                                                                    .team,
                                                            ];
                                                            next[i] = {
                                                                ...row,
                                                                role: v,
                                                            };
                                                            setTeam(next);
                                                        }}
                                                    >
                                                        <SelectTrigger>
                                                            <SelectValue />
                                                        </SelectTrigger>
                                                        <SelectContent>
                                                            {options.teamRoles.map(
                                                                (o) => (
                                                                    <SelectItem
                                                                        key={
                                                                            o.value
                                                                        }
                                                                        value={String(
                                                                            o.value,
                                                                        )}
                                                                    >
                                                                        {
                                                                            o.label
                                                                        }
                                                                    </SelectItem>
                                                                ),
                                                            )}
                                                        </SelectContent>
                                                    </Select>
                                                </div>
                                                {form.data.team.length > 1 && (
                                                    <Button
                                                        type="button"
                                                        variant="ghost"
                                                        size="icon-sm"
                                                        onClick={() =>
                                                            setTeam(
                                                                form.data.team.filter(
                                                                    (_, j) =>
                                                                        j !== i,
                                                                ),
                                                            )
                                                        }
                                                    >
                                                        <Trash2 />
                                                    </Button>
                                                )}
                                            </div>
                                        ))}
                                        <InputError
                                            message={form.errors.team}
                                        />
                                        <Button
                                            type="button"
                                            variant="outline"
                                            size="sm"
                                            onClick={() =>
                                                setTeam([
                                                    ...form.data.team,
                                                    {
                                                        user_id: null,
                                                        role: 'counsel',
                                                    },
                                                ])
                                            }
                                        >
                                            <Plus /> Add member
                                        </Button>
                                    </CardContent>
                                </Card>

                                <Card>
                                    <CardHeader>
                                        <CardTitle>Parties</CardTitle>
                                    </CardHeader>
                                    <CardContent className="space-y-3">
                                        {form.data.parties.length === 0 && (
                                            <p className="text-sm text-muted-foreground">
                                                No parties added yet.
                                            </p>
                                        )}
                                        {form.data.parties.map((row, i) => (
                                            <div
                                                key={i}
                                                className="flex flex-wrap items-end gap-2"
                                            >
                                                <div className="grid flex-1 gap-2">
                                                    <Label>Name</Label>
                                                    <Input
                                                        value={row.name}
                                                        onChange={(e) => {
                                                            const next = [
                                                                ...form.data
                                                                    .parties,
                                                            ];
                                                            next[i] = {
                                                                ...row,
                                                                name: e.target
                                                                    .value,
                                                            };
                                                            setParties(next);
                                                        }}
                                                    />
                                                </div>
                                                <div className="grid w-44 gap-2">
                                                    <Label>Role</Label>
                                                    <Select
                                                        value={row.role}
                                                        onValueChange={(v) => {
                                                            const next = [
                                                                ...form.data
                                                                    .parties,
                                                            ];
                                                            next[i] = {
                                                                ...row,
                                                                role: v,
                                                            };
                                                            setParties(next);
                                                        }}
                                                    >
                                                        <SelectTrigger>
                                                            <SelectValue placeholder="Role" />
                                                        </SelectTrigger>
                                                        <SelectContent>
                                                            {options.partyRoles.map(
                                                                (o) => (
                                                                    <SelectItem
                                                                        key={
                                                                            o.value
                                                                        }
                                                                        value={String(
                                                                            o.value,
                                                                        )}
                                                                    >
                                                                        {
                                                                            o.label
                                                                        }
                                                                    </SelectItem>
                                                                ),
                                                            )}
                                                        </SelectContent>
                                                    </Select>
                                                </div>
                                                <Button
                                                    type="button"
                                                    variant="ghost"
                                                    size="icon-sm"
                                                    onClick={() =>
                                                        setParties(
                                                            form.data.parties.filter(
                                                                (_, j) =>
                                                                    j !== i,
                                                            ),
                                                        )
                                                    }
                                                >
                                                    <Trash2 />
                                                </Button>
                                            </div>
                                        ))}
                                        <Button
                                            type="button"
                                            variant="outline"
                                            size="sm"
                                            onClick={() =>
                                                setParties([
                                                    ...form.data.parties,
                                                    {
                                                        name: '',
                                                        role: 'defendant',
                                                        phone: '',
                                                        address: '',
                                                        notes: '',
                                                    },
                                                ])
                                            }
                                        >
                                            <Plus /> Add party
                                        </Button>
                                    </CardContent>
                                </Card>
                            </>
                        )}
                    </div>

                    {!editing && (
                        <div className="lg:col-span-1">
                            <ConflictCheckWidget name={form.data.title} />
                        </div>
                    )}
                </div>
            </form>
        </>
    );
}
