import { Button } from '@/components/ui/button';
import { Calendar } from '@/components/ui/calendar';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { useForm } from '@inertiajs/react';
import AppLayout from '@/layouts/app-layout';
import { Head } from '@inertiajs/react';
import { type BreadcrumbItem } from '@/types';
import InputError from '@/components/input-error';
import { format } from 'date-fns';
import { CalendarIcon } from 'lucide-react';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { cn } from '@/lib/utils';
import { Textarea } from '@/components/ui/textarea';
import { useState, useEffect } from 'react';

interface TransactionFormProps {
    mode: 'create' | 'edit';
    patients: Array<{ id: string; name: string }>;
    registrations: Array<{ id: string; registration_number: string; patient_name: string }>;
    insurances: Array<{ id: string; name: string }>;
    procedures: Array<{ id: string; code: string; name: string }>;
    employees: Array<{ id: string; name: string }>;
    paymentMethods: Record<string, string>;
    statusOptions: Record<string, string>;
    transaction?: {
        id?: string;
        transaction_number: string;
        registration_id?: string;
        patient_id?: string;
        insurance_id?: string;
        procedure_id?: string;
        employee_id?: string;
        service_name: string;
        description?: string;
        transaction_datetime: string;
        subtotal: number;
        tax_amount: number;
        discount_amount: number;
        grand_total: number;
        payment_method: string;
        status: string;
        paid_amount: number;
        insurance_covered_amount: number;
        details?: string;
        notes?: string;
    };
}

const breadcrumbs: BreadcrumbItem[] = [
    { title: 'Dashboard', href: '/dashboard' },
    { title: 'Transaksi', href: '/transactions' },
    { title: 'Form', href: '#' },
];

const toLocalISOString = (date: Date) => {
    const offset = date.getTimezoneOffset();
    const localDate = new Date(date.getTime() - (offset * 60 * 1000));
    return localDate.toISOString().split('T')[0];
};

export default function TransactionForm({
        mode,
        patients,
        registrations,
        insurances,
        procedures,
        employees,
        paymentMethods,
        statusOptions,
        transaction
    }: TransactionFormProps) {
    const { data, setData, post, put, processing, errors, reset } = useForm({
        transaction_number: transaction?.transaction_number || '',
        registration_id: transaction?.registration_id || '',
        patient_id: transaction?.patient_id || '',
        insurance_id: transaction?.insurance_id || '',
        procedure_id: transaction?.procedure_id || '',
        employee_id: transaction?.employee_id || '',
        service_name: transaction?.service_name || '',
        transaction_datetime: transaction?.transaction_datetime || toLocalISOString(new Date()),
        subtotal: transaction?.subtotal || 0,
        tax_amount: transaction?.tax_amount || 0,
        discount_amount: transaction?.discount_amount || 0,
        grand_total: transaction?.grand_total || 0,
        payment_method: transaction?.payment_method || 'cash',
        status: transaction?.status || 'pending',
        paid_amount: transaction?.paid_amount || 0,
        insurance_covered_amount: transaction?.insurance_covered_amount || 0,
        notes: transaction?.notes || '',
        details: transaction?.details || '',
    });

    const [registrationSelected, setRegistrationSelected] = useState<boolean>(false);

    useEffect(() => {
        const calculatedGrandTotal = data.subtotal + data.tax_amount - data.discount_amount;
        setData('grand_total', calculatedGrandTotal);

        if (data.payment_method === 'insurance') {
            const insuranceCovered = calculatedGrandTotal * 0.8; // Example: insurance covers 80%
            setData('insurance_covered_amount', insuranceCovered);
            setData('paid_amount', calculatedGrandTotal - insuranceCovered);
        } else {
            setData('insurance_covered_amount', 0);
            setData('paid_amount', calculatedGrandTotal);
        }
    }, [data.subtotal, data.tax_amount, data.discount_amount, data.payment_method]);

    useEffect(() => {
        if (data.registration_id) {
            const selectedRegistration = registrations.find(r => r.id === data.registration_id);
            if (selectedRegistration) {
                setRegistrationSelected(true);
                const patient = patients.find(p => p.name === selectedRegistration.patient_name);
                if (patient) {
                    setData('patient_id', patient.id);
                }
            }
        } else {
            setRegistrationSelected(false);
        }
    }, [data.registration_id, registrations, patients]);

    useEffect(() => {
        if (data.procedure_id) {
            const selectedProcedure = procedures.find(p => p.id === data.procedure_id);
            if (selectedProcedure) {
                setData('service_name', selectedProcedure.name);
            }
        }
    }, [data.procedure_id, procedures]);

    const onSubmit = (e: React.FormEvent) => {
        e.preventDefault();
        if (mode === 'create') {
            post(route('transactions.store'), {
                onSuccess: () => reset(),
            });
        } else {
            put(route('transactions.update', transaction?.id), {
                preserveScroll: true,
            });
        }
    };

    const formatCurrency = (value: number) => {
        return new Intl.NumberFormat('id-ID', {
            style: 'currency',
            currency: 'IDR',
            minimumFractionDigits: 0,
        }).format(value);
    };

    return (
        <AppLayout breadcrumbs={breadcrumbs}>
            <Head title={`${mode === 'create' ? 'Tambah' : 'Edit'} Transaksi`} />

            <div className="flex h-full flex-1 flex-col gap-4 rounded-xl p-4">
                <div className="flex items-center justify-between">
                    <h1 className="text-2xl font-bold">
                        {mode === 'create' ? 'Tambah Transaksi Baru' : 'Edit Data Transaksi'}
                    </h1>
                    {mode === 'edit' && (
                        <span className="text-xl">
                            No. Transaksi {data.transaction_number}
                        </span>
                    )}
                </div>

                <div>
                    <form onSubmit={onSubmit} className="space-y-6">
                        <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
                            <div className="space-y-2">
                                <Label htmlFor="registration_id">No. Registrasi</Label>
                                <Select
                                    value={data.registration_id}
                                    onValueChange={(value) => setData('registration_id', value)}
                                >
                                    <SelectTrigger>
                                        <SelectValue placeholder="Pilih nomor registrasi" />
                                    </SelectTrigger>
                                    <SelectContent>
                                        <SelectItem value="none">Tanpa registrasi</SelectItem>
                                        {registrations.map((registration) => (
                                            <SelectItem key={registration.id} value={registration.id}>
                                                {registration.registration_number} - {registration.patient_name}
                                            </SelectItem>
                                        ))}
                                    </SelectContent>
                                </Select>
                                <InputError message={errors.registration_id} />
                            </div>

                            <div className="space-y-2">
                                <Label htmlFor="patient_id">Pasien *</Label>
                                <Select
                                    value={data.patient_id}
                                    onValueChange={(value) => setData('patient_id', value)}
                                    disabled={registrationSelected}
                                >
                                    <SelectTrigger>
                                        <SelectValue placeholder="Pilih pasien" />
                                    </SelectTrigger>
                                    <SelectContent>
                                        {patients.map((patient) => (
                                            <SelectItem key={patient.id} value={patient.id}>
                                                {patient.name}
                                            </SelectItem>
                                        ))}
                                    </SelectContent>
                                </Select>
                                <InputError message={errors.patient_id} />
                            </div>

                            <div className="space-y-2">
                                <Label htmlFor="procedure_id">Prosedur</Label>
                                <Select
                                    value={data.procedure_id}
                                    onValueChange={(value) => setData('procedure_id', value)}
                                >
                                    <SelectTrigger>
                                        <SelectValue placeholder="Pilih prosedur" />
                                    </SelectTrigger>
                                    <SelectContent>
                                        <SelectItem value="manual">Manual Input</SelectItem>
                                        {procedures.map((procedure) => (
                                            <SelectItem key={procedure.id} value={procedure.id}>
                                                {procedure.code} - {procedure.name}
                                            </SelectItem>
                                        ))}
                                    </SelectContent>
                                </Select>
                                <InputError message={errors.procedure_id} />
                            </div>

                            <div className="space-y-2">
                                <Label htmlFor="service_name">Nama Layanan *</Label>
                                <Input
                                    id="service_name"
                                    value={data.service_name}
                                    onChange={(e) => setData('service_name', e.target.value)}
                                    placeholder="Nama layanan"
                                />
                                <InputError message={errors.service_name} />
                            </div>

                            <div className="space-y-2">
                                <Label htmlFor="employee_id">Pelaksana Layanan</Label>
                                <Select
                                    value={data.employee_id}
                                    onValueChange={(value) => setData('employee_id', value)}
                                >
                                    <SelectTrigger>
                                        <SelectValue placeholder="Pilih pelaksana" />
                                    </SelectTrigger>
                                    <SelectContent>
                                        {employees.map((employee) => (
                                            <SelectItem key={employee.id} value={employee.id}>
                                                {employee.name}
                                            </SelectItem>
                                        ))}
                                    </SelectContent>
                                </Select>
                                <InputError message={errors.employee_id} />
                            </div>

                            <div className="space-y-2">
                                <Label htmlFor="transaction_datetime">Tanggal/Waktu Transaksi *</Label>
                                <Popover>
                                    <PopoverTrigger asChild>
                                        <Button
                                            variant={"outline"}
                                            className={cn(
                                                "w-full justify-start text-left font-normal",
                                                !data.transaction_datetime && "text-muted-foreground"
                                            )}
                                        >
                                            <CalendarIcon className="mr-2 h-4 w-4" />
                                            {data.transaction_datetime ? (
                                                format(new Date(data.transaction_datetime), "dd/MM/yyyy HH:mm")
                                            ) : (
                                                <span>Pilih tanggal/waktu</span>
                                            )}
                                        </Button>
                                    </PopoverTrigger>
                                    <PopoverContent className="w-auto p-0">
                                        <Calendar
                                            mode="single"
                                            selected={data.transaction_datetime ? new Date(data.transaction_datetime) : undefined}
                                            onSelect={(date) => date && setData('transaction_datetime', toLocalISOString(date))}
                                            initialFocus
                                        />
                                    </PopoverContent>
                                </Popover>
                                <InputError message={errors.transaction_datetime} />
                            </div>

                            {/* Financial Section */}
                            <div className="space-y-2">
                                <Label htmlFor="subtotal">Subtotal *</Label>
                                <Input
                                    id="subtotal"
                                    type="number"
                                    value={data.subtotal}
                                    onChange={(e) => setData('subtotal', Math.max(0, parseFloat(e.target.value) || 0))}
                                    placeholder="Subtotal"
                                />
                                <InputError message={errors.subtotal} />
                            </div>

                            <div className="space-y-2">
                                <Label htmlFor="tax_amount">Pajak *</Label>
                                <Input
                                    id="tax_amount"
                                    type="number"
                                    value={data.tax_amount}
                                    onChange={(e) => setData('tax_amount', Math.max(0, parseFloat(e.target.value) || 0))}
                                    placeholder="Jumlah pajak"
                                />
                                <InputError message={errors.tax_amount} />
                            </div>

                            <div className="space-y-2">
                                <Label htmlFor="discount_amount">Diskon *</Label>
                                <Input
                                    id="discount_amount"
                                    type="number"
                                    value={data.discount_amount}
                                    onChange={(e) => setData('discount_amount', Math.max(0, parseFloat(e.target.value) || 0))}
                                    placeholder="Jumlah diskon"
                                />
                                <InputError message={errors.discount_amount} />
                            </div>

                            <div className="space-y-2">
                                <Label>Grand Total</Label>
                                <div className="p-2 font-semibold text-xl">
                                    {formatCurrency(data.grand_total)}
                                </div>
                                <InputError message={errors.grand_total} />
                            </div>

                            <div className="space-y-2">
                                <Label htmlFor="payment_method">Metode Pembayaran *</Label>
                                <Select
                                    value={data.payment_method}
                                    onValueChange ={(value) => {
                                        setData('payment_method', value);
                                        if (value === 'insurance' && data.insurance_id) {
                                            const insuranceCovered = data.grand_total * 0.8;
                                            setData('insurance_covered_amount', insuranceCovered);
                                            setData('paid_amount', data.grand_total - insuranceCovered);
                                        } else {
                                            setData('insurance_covered_amount', 0);
                                            setData('paid_amount', data.grand_total);
                                        }
                                    }}
                                >
                                    <SelectTrigger>
                                        <SelectValue placeholder="Pilih metode pembayaran" />
                                    </SelectTrigger>
                                    <SelectContent>
                                        {Object.entries(paymentMethods).map(([key, value]) => (
                                            <SelectItem key={key} value={key}>
                                                {value}
                                            </SelectItem>
                                        ))}
                                    </SelectContent>
                                </Select>
                                <InputError message={errors.payment_method} />
                            </div>

                            <div className="space-y-2">
                                <Label htmlFor="status">Status Pembayaran *</Label>
                                <Select
                                    value={data.status}
                                    onValueChange={(value) => setData('status', value)}
                                >
                                    <SelectTrigger>
                                        <SelectValue placeholder="Pilih status pembayaran" />
                                    </SelectTrigger>
                                    <SelectContent>
                                        {Object.entries(statusOptions).map(([key, value]) => (
                                            <SelectItem key={key} value={key}>
                                                {value}
                                            </SelectItem>
                                        ))}
                                    </SelectContent>
                                </Select>
                                <InputError message={errors.status} />
                            </div>

                            {data.payment_method === 'insurance' && (
                                <>
                                    <div className="space-y-2">
                                        <Label htmlFor="insurance_id">Asuransi *</Label>
                                        <Select
                                            value={data.insurance_id}
                                            onValueChange={(value) => {
                                                setData('insurance_id', value);
                                                const insuranceCovered = data.grand_total * 0.8;
                                                setData('insurance_covered_amount', insuranceCovered);
                                                setData('paid_amount', data.grand_total - insuranceCovered);
                                            }}
                                        >
                                            <SelectTrigger>
                                                <SelectValue placeholder="Pilih asuransi" />
                                            </SelectTrigger>
                                            <SelectContent>
                                                {insurances.map((insurance) => (
                                                    <SelectItem key={insurance.id} value={insurance.id}>
                                                        {insurance.name}
                                                    </SelectItem>
                                                ))}
                                            </SelectContent>
                                        </Select>
                                        <InputError message={errors.insurance_id} />
                                    </div>

                                    <div className="space-y-2">
                                        <Label htmlFor="insurance_covered_amount">Dibayar Asuransi *</Label>
                                        <Input
                                            id="insurance_covered_amount"
                                            type="number"
                                            value={data.insurance_covered_amount}
                                            onChange={(e) => {
                                                const insuranceCovered = Math.max(0, parseFloat(e.target.value) || 0);
                                                setData('insurance_covered_amount', insuranceCovered);
                                                setData('paid_amount', data.grand_total - insuranceCovered);
                                            }}
                                            placeholder="Jumlah dibayar asuransi"
                                        />
                                        <InputError message={errors.insurance_covered_amount} />
                                    </div>
                                </>
                            )}

                            <div className="space-y-2">
                                <Label htmlFor="paid_amount">Jumlah Pembayaran *</Label>
                                <Input
                                    id="paid_amount"
                                    type="number"
                                    value={data.paid_amount}
                                    onChange={(e) => {
                                        const paidAmount = Math.max(0, parseFloat(e.target.value) || 0);
                                        setData('paid_amount', paidAmount);
                                        if (data.payment_method === 'insurance') {
                                            setData('insurance_covered_amount', data.grand_total - paidAmount);
                                        }
                                    }}
                                    placeholder="Jumlah pembayaran"
                                />
                                <InputError message={errors.paid_amount} />
                            </div>

                            <div className="space-y-2 col-span-full">
                                <Label htmlFor="details">Detail Layanan *</Label>
                                <Textarea
                                    id="details"
                                    value={data.details}
                                    onChange={(e) => setData('details', e.target.value)}
                                    placeholder="Detail layanan yang diberikan"
                                />
                                <InputError message={errors.details} />
                            </div>

                            <div className="space-y-2 col-span-full">
                                <Label htmlFor="notes">Catatan</Label>
                                <Textarea
                                    id="notes"
                                    value={data.notes}
                                    onChange={(e) => setData('notes', e.target.value)}
                                    placeholder="Catatan tambahan"
                                />
                                <InputError message={errors.notes} />
                            </div>
                        </div>

                        <div className="flex justify-end gap-2">
                            <Button variant="outline" type="button" onClick ={() => window.history.back()}>
                                Batal
                            </Button>
                            <Button type="submit" disabled={processing}>
                                {mode === 'create' ? 'Simpan' : 'Perbarui'} Transaksi
                            </Button>
                        </div>
                    </form>
                </div>
            </div>
        </AppLayout>
    );
}
