import { useForm } from '@inertiajs/react';
import type { FormEvent } from 'react';
import FixedAssetController from '@/actions/App/Http/Controllers/Admin/FixedAssetController';
import InputError from '@/components/input-error';
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 { Textarea } from '@/components/ui/textarea';

export type AccountOption = { id: number; code: string; label: string };
export type MethodOption = { value: string; label: string };

export type FixedAssetFormData = {
    id: number;
    label: string;
    acquisition_date: string | null;
    acquisition_cost: string | number;
    residual_value: string | number;
    useful_life_months: number;
    depreciation_method: string;
    asset_account_id: number;
    depreciation_account_id: number;
    expense_account_id: number;
    notes: string | null;
    supplier_invoice_id?: number | null;
};

export type SupplierInvoiceOption = {
    id: number;
    code: string;
    reference: string;
    amount: string;
    subtotal: string | null;
    due_date: string | null;
    is_fixed_asset: boolean;
    supplier: { id: number; name: string } | null;
};

export type FixedAssetPrefill = {
    supplier_invoice_id: number;
    label: string;
    acquisition_cost: string;
    acquisition_date: string;
};

type Accounts = {
    asset_accounts: AccountOption[];
    depreciation_accounts: AccountOption[];
    expense_accounts: AccountOption[];
};

type Props = {
    accounts: Accounts;
    depreciationMethods: MethodOption[];
    asset?: FixedAssetFormData | null;
    supplierInvoices?: SupplierInvoiceOption[];
    prefill?: FixedAssetPrefill | null;
    onCancel: () => void;
};

export function FixedAssetForm({
    accounts,
    depreciationMethods,
    asset = null,
    supplierInvoices = [],
    prefill = null,
    onCancel,
}: Props) {
    const isEditing = asset !== null;

    const form = useForm({
        label: asset?.label ?? prefill?.label ?? '',
        acquisition_date:
            asset?.acquisition_date ??
            prefill?.acquisition_date ??
            new Date().toISOString().slice(0, 10),
        acquisition_cost: asset?.acquisition_cost ?? prefill?.acquisition_cost ?? '',
        residual_value: asset?.residual_value ?? '0',
        useful_life_months: asset?.useful_life_months ?? 60,
        depreciation_method:
            asset?.depreciation_method ?? depreciationMethods[0]?.value ?? 'linear',
        asset_account_id: asset ? String(asset.asset_account_id) : '',
        depreciation_account_id: asset
            ? String(asset.depreciation_account_id)
            : '',
        expense_account_id: asset ? String(asset.expense_account_id) : '',
        notes: asset?.notes ?? '',
        supplier_invoice_id: prefill?.supplier_invoice_id
            ? String(prefill.supplier_invoice_id)
            : '',
    });

    function onSupplierInvoiceChange(value: string) {
        form.setData('supplier_invoice_id', value);

        if (!value) {
            return;
        }

        const invoice = supplierInvoices.find(
            (item) => String(item.id) === value,
        );

        if (invoice === undefined) {
            return;
        }

        form.setData((current) => ({
            ...current,
            supplier_invoice_id: value,
            label: current.label || `Immobilisation — facture ${invoice.reference}`,
            acquisition_cost:
                invoice.subtotal ?? invoice.amount ?? current.acquisition_cost,
            acquisition_date: invoice.due_date ?? current.acquisition_date,
        }));
    }

    function submit(event: FormEvent) {
        event.preventDefault();

        const payload = {
            ...form.data,
            acquisition_cost: Number(form.data.acquisition_cost),
            residual_value: Number(form.data.residual_value),
            useful_life_months: Number(form.data.useful_life_months),
            asset_account_id: Number(form.data.asset_account_id),
            depreciation_account_id: Number(form.data.depreciation_account_id),
            expense_account_id: Number(form.data.expense_account_id),
            notes: form.data.notes || null,
            supplier_invoice_id: form.data.supplier_invoice_id
                ? Number(form.data.supplier_invoice_id)
                : null,
        };

        form.transform(() => payload);

        if (isEditing && asset) {
            form.put(FixedAssetController.update.url(asset.id));
            return;
        }

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

    return (
        <form onSubmit={submit} className="space-y-6">
            <Card>
                <CardHeader>
                    <CardTitle>Identification</CardTitle>
                </CardHeader>
                <CardContent className="grid gap-4 sm:grid-cols-2">
                    {!isEditing && supplierInvoices.length > 0 && (
                        <div className="grid gap-2 sm:col-span-2">
                            <Label>Facture fournisseur (optionnel)</Label>
                            <Select
                                value={form.data.supplier_invoice_id || undefined}
                                onValueChange={onSupplierInvoiceChange}
                            >
                                <SelectTrigger>
                                    <SelectValue placeholder="Sélectionner une facture…" />
                                </SelectTrigger>
                                <SelectContent>
                                    {supplierInvoices.map((invoice) => (
                                        <SelectItem
                                            key={invoice.id}
                                            value={String(invoice.id)}
                                        >
                                            {invoice.code} — {invoice.reference}
                                            {invoice.supplier
                                                ? ` (${invoice.supplier.name})`
                                                : ''}
                                        </SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>
                            <InputError message={form.errors.supplier_invoice_id} />
                        </div>
                    )}
                    <div className="grid gap-2 sm:col-span-2">
                        <Label>Libellé</Label>
                        <Input
                            value={form.data.label}
                            onChange={(e) => form.setData('label', e.target.value)}
                            required
                        />
                        <InputError message={form.errors.label} />
                    </div>
                    <div className="grid gap-2">
                        <Label>Date d'acquisition</Label>
                        <Input
                            type="date"
                            value={form.data.acquisition_date}
                            onChange={(e) =>
                                form.setData('acquisition_date', e.target.value)
                            }
                            required
                        />
                    </div>
                    <div className="grid gap-2">
                        <Label>Valeur d'acquisition</Label>
                        <Input
                            type="number"
                            step="0.01"
                            min="0.01"
                            value={form.data.acquisition_cost}
                            onChange={(e) =>
                                form.setData('acquisition_cost', e.target.value)
                            }
                            required
                        />
                    </div>
                    <div className="grid gap-2">
                        <Label>Valeur résiduelle</Label>
                        <Input
                            type="number"
                            step="0.01"
                            min="0"
                            value={form.data.residual_value}
                            onChange={(e) =>
                                form.setData('residual_value', e.target.value)
                            }
                        />
                    </div>
                    <div className="grid gap-2">
                        <Label>Durée (mois)</Label>
                        <Input
                            type="number"
                            min="1"
                            value={form.data.useful_life_months}
                            onChange={(e) =>
                                form.setData(
                                    'useful_life_months',
                                    Number(e.target.value),
                                )
                            }
                            required
                        />
                    </div>
                    <div className="grid gap-2 sm:col-span-2">
                        <Label>Méthode d'amortissement</Label>
                        <Select
                            value={form.data.depreciation_method}
                            onValueChange={(value) =>
                                form.setData('depreciation_method', value)
                            }
                        >
                            <SelectTrigger>
                                <SelectValue />
                            </SelectTrigger>
                            <SelectContent>
                                {depreciationMethods.map((method) => (
                                    <SelectItem
                                        key={method.value}
                                        value={method.value}
                                    >
                                        {method.label}
                                    </SelectItem>
                                ))}
                            </SelectContent>
                        </Select>
                    </div>
                </CardContent>
            </Card>

            <Card>
                <CardHeader>
                    <CardTitle>Comptes comptables</CardTitle>
                </CardHeader>
                <CardContent className="grid gap-4">
                    {(
                        [
                            ['asset_account_id', 'Compte d\'immobilisation', accounts.asset_accounts],
                            ['depreciation_account_id', 'Compte d\'amortissement', accounts.depreciation_accounts],
                            ['expense_account_id', 'Compte de dotation', accounts.expense_accounts],
                        ] as const
                    ).map(([field, label, options]) => (
                        <div key={field} className="grid gap-2">
                            <Label>{label}</Label>
                            <Select
                                value={form.data[field] || undefined}
                                onValueChange={(value) => form.setData(field, value)}
                            >
                                <SelectTrigger>
                                    <SelectValue placeholder="Choisir un compte…" />
                                </SelectTrigger>
                                <SelectContent>
                                    {options.map((account) => (
                                        <SelectItem
                                            key={account.id}
                                            value={String(account.id)}
                                        >
                                            {account.code} — {account.label}
                                        </SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>
                            <InputError message={form.errors[field]} />
                        </div>
                    ))}
                    <div className="grid gap-2">
                        <Label>Notes</Label>
                        <Textarea
                            value={form.data.notes}
                            onChange={(e) => form.setData('notes', e.target.value)}
                            rows={2}
                        />
                    </div>
                </CardContent>
            </Card>

            <div className="flex justify-end gap-2">
                <Button type="button" variant="outline" onClick={onCancel}>
                    Annuler
                </Button>
                <Button type="submit" disabled={form.processing}>
                    {isEditing ? 'Enregistrer' : 'Créer'}
                </Button>
            </div>
        </form>
    );
}
