import { Head, Link, useForm } from '@inertiajs/react';
import axios from 'axios';
import { ArrowLeft } from 'lucide-react';
import { useEffect, useRef, useState } from 'react';

import InputError from '@/components/input-error';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { MaskedInput } from '@/components/ui/masked-input';
import { SearchableSelect } from '@/components/ui/searchable-select';
import {
    Select,
    SelectContent,
    SelectGroup,
    SelectItem,
    SelectLabel,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import { Textarea } from '@/components/ui/textarea';
import AppLayout from '@/layouts/app-layout';
import {
    toastError,
    toastFinishLoading,
    toastLoading,
    toastSuccess,
} from '@/lib/toast';
import membersRoutes from '@/routes/members';
import type {
    Branch,
    BreadcrumbItem,
    District,
    Member,
    Province,
    Regency,
    Village,
} from '@/types';

interface PageProps {
    member: Member & { branch: { id: number; name: string } };
    branches: Branch[];
    provinces: Province[];
    regencies: Regency[];
    districts: District[];
    villages: Village[];
    users: { id: number; name: string }[];
}

const breadcrumbs: BreadcrumbItem[] = [
    {
        title: 'Anggota',
        href: membersRoutes.index().url,
    },
    {
        title: 'Edit Anggota',
        href: '#',
    },
];

export default function Edit({
    member,
    branches,
    provinces,
    regencies: initialRegencies,
    districts: initialDistricts,
    villages: initialVillages,
    users,
}: PageProps) {
    // Helper to format date for HTML date input (YYYY-MM-DD)
    const formatForDateInput = (
        dateStr: string | null | undefined | Date,
    ): string => {
        if (!dateStr) return '';

        let date: Date;

        // Handle if it's already a Date object
        if (dateStr instanceof Date) {
            date = dateStr;
        } else {
            // Handle if it's a string
            date = new Date(dateStr);
        }

        // Check if date is valid
        if (isNaN(date.getTime())) return '';

        const year = date.getFullYear();
        const month = String(date.getMonth() + 1).padStart(2, '0');
        const day = String(date.getDate()).padStart(2, '0');
        return `${year}-${month}-${day}`;
    };

    // Helper to safely convert value to string for form fields
    const safeString = (value: string | null | number | undefined): string => {
        if (value === null || value === undefined) return '';
        return String(value);
    };

    const form = useForm({
        branch_id: String(member.branch?.id ?? ''),
        id_number: safeString(member.id_number),
        id_type: safeString(member.id_type),
        name: safeString(member.name),
        birth_date: formatForDateInput(member.birth_date),
        gender: member.gender ?? '',
        phone: safeString(member.phone),
        email: safeString(member.email),
        address: safeString(member.address),
        province: safeString(member.province),
        city: safeString(member.city),
        district: safeString(member.district),
        village: safeString(member.village),
        referred_by: safeString(member.created_by),
    });

    const [regencies, setRegencies] = useState<Regency[]>(initialRegencies);
    const [districts, setDistricts] = useState<District[]>(initialDistricts);
    const [villages, setVillages] = useState<Village[]>(initialVillages);
    const [loadingRegencies, setLoadingRegencies] = useState(false);
    const [loadingDistricts, setLoadingDistricts] = useState(false);
    const [loadingVillages, setLoadingVillages] = useState(false);

    // Track previous values to prevent resetting fields on initial load
    const prevProvince = useRef(form.data.province);
    const prevCity = useRef(form.data.city);
    const prevDistrict = useRef(form.data.district);

    // Fetch regencies when province changes
    useEffect(() => {
        // Only trigger if province actually changed (avoids initial load reset)
        if (form.data.province === prevProvince.current) {
            return;
        }

        const province = form.data.province;
        prevProvince.current = province;

        if (province) {
            setTimeout(() => setLoadingRegencies(true), 0);
            axios
                .get('/api/regions/regencies', {
                    params: { province_id: province },
                })
                .then((response) => {
                    setRegencies(response.data);
                })
                .catch(() => {
                    toastError('Gagal memuat data kabupaten/kota');
                })
                .finally(() => {
                    setLoadingRegencies(false);
                });
        } else {
            setTimeout(() => {
                setRegencies([]);
                setDistricts([]);
                setVillages([]);
            }, 0);
        }
    }, [form.data.province]);

    // Fetch districts when regency changes
    useEffect(() => {
        // Only trigger if city actually changed
        if (form.data.city === prevCity.current) {
            return;
        }

        const city = form.data.city;
        prevCity.current = city;

        if (city) {
            setTimeout(() => setLoadingDistricts(true), 0);
            axios
                .get('/api/regions/districts', {
                    params: { regency_id: city },
                })
                .then((response) => {
                    setDistricts(response.data);
                })
                .catch(() => {
                    toastError('Gagal memuat data kecamatan');
                })
                .finally(() => {
                    setLoadingDistricts(false);
                });
        } else {
            setTimeout(() => {
                setDistricts([]);
                setVillages([]);
            }, 0);
        }
    }, [form.data.city]);

    // Fetch villages when district changes
    useEffect(() => {
        // Only trigger if district actually changed
        if (form.data.district === prevDistrict.current) {
            return;
        }

        const district = form.data.district;
        prevDistrict.current = district;

        if (district) {
            setTimeout(() => setLoadingVillages(true), 0);
            axios
                .get('/api/regions/villages', {
                    params: { district_id: district },
                })
                .then((response) => {
                    setVillages(response.data);
                })
                .catch(() => {
                    toastError('Gagal memuat data kelurahan/desa');
                })
                .finally(() => {
                    setLoadingVillages(false);
                });
        } else {
            setTimeout(() => {
                setVillages([]);
            }, 0);
        }
    }, [form.data.district]);

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

        form.put(membersRoutes.update({ member: member.id }).url, {
            onStart: () => toastLoading('Memperbarui data anggota....'),
            onSuccess: () => {
                toastSuccess('Anggota berhasil diperbarui');
                toastFinishLoading();
            },
            onError: () => {
                toastError('Gagal memperbarui anggota');
            },
        });
    };

    return (
        <AppLayout breadcrumbs={breadcrumbs}>
            <Head title={`Edit: ${member.name}`} />

            <div className="flex h-full flex-1 flex-col gap-4 rounded-xl p-4">
                {/* Header */}
                <div className="flex items-center gap-4">
                    <Button variant="outline" size="icon" asChild>
                        <Link href={membersRoutes.index().url}>
                            <ArrowLeft className="h-4 w-4" />
                        </Link>
                    </Button>
                    <div className="flex flex-col gap-1">
                        <h1 className="text-2xl font-black">Edit Anggota</h1>
                        <span className="text-sm text-muted-foreground">
                            Perbarui informasi anggota: {member.name}
                        </span>
                    </div>
                </div>

                {/* Form */}
                <form onSubmit={handleSubmit} className="space-y-6">
                    <div className="grid gap-6 rounded-lg border p-6">
                        <div className="grid gap-4 md:grid-cols-2">
                            {/* Nama Lengkap */}
                            <div className="space-y-2">
                                <Label htmlFor="name">
                                    Nama Lengkap{' '}
                                    <span className="text-destructive">*</span>
                                </Label>
                                <Input
                                    id="name"
                                    value={form.data.name}
                                    onChange={(e) =>
                                        form.setData('name', e.target.value)
                                    }
                                    placeholder="Masukkan nama lengkap"
                                    required
                                />
                                {form.errors.name && (
                                    <InputError message={form.errors.name} />
                                )}
                            </div>

                            {/* Nomor Identitas */}
                            <div className="space-y-2">
                                <Label htmlFor="id_number">
                                    Nomor Identitas (NIK){' '}
                                    <span className="text-destructive">*</span>
                                </Label>
                                <MaskedInput
                                    id="id_number"
                                    format="#### #### #### ####"
                                    mask="_"
                                    value={form.data.id_number}
                                    onValueChange={(values) => {
                                        form.setData('id_number', values.value);
                                    }}
                                    placeholder="____ ____ ____ ____"
                                    required
                                />
                                {form.errors.id_number && (
                                    <InputError
                                        message={form.errors.id_number}
                                    />
                                )}
                            </div>

                            {/* Tipe Identitas */}
                            <div className="space-y-2">
                                <Label htmlFor="id_type">
                                    Tipe Identitas{' '}
                                    <span className="text-destructive">*</span>
                                </Label>
                                <Select
                                    value={form.data.id_type}
                                    onValueChange={(value) =>
                                        form.setData('id_type', value)
                                    }
                                    required
                                >
                                    <SelectTrigger>
                                        <SelectValue placeholder="Pilih tipe identitas" />
                                    </SelectTrigger>
                                    <SelectContent>
                                        <SelectGroup>
                                            <SelectLabel>
                                                Tipe Identitas
                                            </SelectLabel>
                                            <SelectItem value="KTP">
                                                KTP
                                            </SelectItem>
                                            <SelectItem value="SIM">
                                                SIM
                                            </SelectItem>
                                            <SelectItem value="Passport">
                                                Passport
                                            </SelectItem>
                                        </SelectGroup>
                                    </SelectContent>
                                </Select>
                                {form.errors.id_type && (
                                    <InputError message={form.errors.id_type} />
                                )}
                            </div>

                            {/* Jenis Kelamin */}
                            <div className="space-y-2">
                                <Label htmlFor="gender">
                                    Jenis Kelamin{' '}
                                    <span className="text-destructive">*</span>
                                </Label>
                                <Select
                                    value={form.data.gender}
                                    onValueChange={(value) =>
                                        form.setData('gender', value)
                                    }
                                    required
                                >
                                    <SelectTrigger>
                                        <SelectValue placeholder="Pilih jenis kelamin" />
                                    </SelectTrigger>
                                    <SelectContent>
                                        <SelectGroup>
                                            <SelectLabel>
                                                Jenis Kelamin
                                            </SelectLabel>
                                            <SelectItem value="male">
                                                Laki-laki
                                            </SelectItem>
                                            <SelectItem value="female">
                                                Perempuan
                                            </SelectItem>
                                        </SelectGroup>
                                    </SelectContent>
                                </Select>
                                {form.errors.gender && (
                                    <InputError message={form.errors.gender} />
                                )}
                            </div>

                            {/* Telepon */}
                            <div className="space-y-2">
                                <Label htmlFor="phone">
                                    Telepon{' '}
                                    <span className="text-destructive">*</span>
                                </Label>
                                <MaskedInput
                                    id="phone"
                                    format="(####) #### #####"
                                    mask="_"
                                    value={form.data.phone}
                                    onValueChange={(values) => {
                                        form.setData('phone', values.value);
                                    }}
                                    placeholder="(08__) ____ "
                                    required
                                />
                                {form.errors.phone && (
                                    <InputError message={form.errors.phone} />
                                )}
                            </div>

                            {/* Email */}
                            <div className="space-y-2">
                                <Label htmlFor="email">Email</Label>
                                <Input
                                    id="email"
                                    value={form.data.email}
                                    onChange={(e) =>
                                        form.setData('email', e.target.value)
                                    }
                                    type="email"
                                    placeholder="email@example.com"
                                />
                                {form.errors.email && (
                                    <InputError message={form.errors.email} />
                                )}
                            </div>

                            {/* Cabang */}
                            <div className="space-y-2">
                                <Label htmlFor="branch_id">
                                    Cabang{' '}
                                    <span className="text-destructive">*</span>
                                </Label>
                                <Select
                                    value={form.data.branch_id}
                                    onValueChange={(value) =>
                                        form.setData('branch_id', value)
                                    }
                                    required
                                >
                                    <SelectTrigger>
                                        <SelectValue placeholder="Pilih cabang" />
                                    </SelectTrigger>
                                    <SelectContent>
                                        <SelectGroup>
                                            <SelectLabel>Cabang</SelectLabel>
                                            {branches.map((branch) => (
                                                <SelectItem
                                                    key={branch.id}
                                                    value={branch.id.toString()}
                                                >
                                                    {branch.name}
                                                </SelectItem>
                                            ))}
                                        </SelectGroup>
                                    </SelectContent>
                                </Select>
                                {form.errors.branch_id && (
                                    <InputError
                                        message={form.errors.branch_id}
                                    />
                                )}
                            </div>

                            {/* Tanggal Lahir */}
                            <div className="space-y-2">
                                <Label htmlFor="birth_date">
                                    Tanggal Lahir{' '}
                                    <span className="text-destructive">*</span>
                                </Label>
                                <Input
                                    id="birth_date"
                                    value={form.data.birth_date}
                                    onChange={(e) =>
                                        form.setData(
                                            'birth_date',
                                            e.target.value,
                                        )
                                    }
                                    type="date"
                                    required
                                />
                                {form.errors.birth_date && (
                                    <InputError
                                        message={form.errors.birth_date}
                                    />
                                )}
                            </div>
                        </div>

                        {/* Alamat & Wilayah */}
                        <div className="grid gap-4 md:grid-cols-2">
                            {/* Alamat */}
                            <div className="space-y-2 md:col-span-2">
                                <Label htmlFor="address">
                                    Alamat Lengkap{' '}
                                    <span className="text-destructive">*</span>
                                </Label>
                                <Textarea
                                    id="address"
                                    value={form.data.address}
                                    onChange={(e) =>
                                        form.setData('address', e.target.value)
                                    }
                                    placeholder="Masukkan alamat lengkap"
                                    rows={3}
                                    required
                                />
                                {form.errors.address && (
                                    <InputError message={form.errors.address} />
                                )}
                            </div>

                            {/* Provinsi */}
                            <div className="space-y-2">
                                <Label htmlFor="province">
                                    Provinsi{' '}
                                    <span className="text-destructive">*</span>
                                </Label>
                                <SearchableSelect
                                    options={provinces.map((p) => ({
                                        value: String(p.id),
                                        label: p.name,
                                    }))}
                                    value={form.data.province}
                                    onValueChange={(value) => {
                                        form.setData((prev) => ({
                                            ...prev,
                                            province: value,
                                            city: '',
                                            district: '',
                                            village: '',
                                        }));
                                        setTimeout(() => {
                                            setDistricts([]);
                                            setVillages([]);
                                        }, 0);
                                    }}
                                    placeholder="Pilih provinsi"
                                    searchPlaceholder="Cari provinsi..."
                                    error={form.errors.province}
                                />
                            </div>

                            {/* Kota/Kabupaten */}
                            <div className="space-y-2">
                                <Label htmlFor="city">
                                    Kota/Kabupaten{' '}
                                    <span className="text-destructive">*</span>
                                </Label>
                                <SearchableSelect
                                    options={regencies.map((r) => ({
                                        value: String(r.id),
                                        label: r.name,
                                    }))}
                                    value={form.data.city}
                                    onValueChange={(value) => {
                                        form.setData((prev) => ({
                                            ...prev,
                                            city: value,
                                            district: '',
                                            village: '',
                                        }));
                                        setTimeout(() => {
                                            setVillages([]);
                                        }, 0);
                                    }}
                                    disabled={!form.data.province}
                                    loading={loadingRegencies}
                                    placeholder={
                                        !form.data.province
                                            ? 'Pilih provinsi terlebih dahulu'
                                            : 'Pilih kota/kabupaten'
                                    }
                                    searchPlaceholder="Cari kota/kabupaten..."
                                    error={form.errors.city}
                                />
                            </div>

                            {/* Kecamatan */}
                            <div className="space-y-2">
                                <Label htmlFor="district">
                                    Kecamatan{' '}
                                    <span className="text-destructive">*</span>
                                </Label>
                                <SearchableSelect
                                    options={districts.map((d) => ({
                                        value: String(d.id),
                                        label: d.name,
                                    }))}
                                    value={form.data.district}
                                    onValueChange={(value) =>
                                        form.setData((prev) => ({
                                            ...prev,
                                            district: value,
                                            village: '',
                                        }))
                                    }
                                    disabled={!form.data.city}
                                    loading={loadingDistricts}
                                    placeholder={
                                        !form.data.city
                                            ? 'Pilih kota/kabupaten terlebih dahulu'
                                            : 'Pilih kecamatan'
                                    }
                                    searchPlaceholder="Cari kecamatan..."
                                    error={form.errors.district}
                                />
                            </div>

                            {/* Kelurahan/Desa */}
                            <div className="space-y-2">
                                <Label htmlFor="village">
                                    Kelurahan/Desa{' '}
                                    <span className="text-destructive">*</span>
                                </Label>
                                <SearchableSelect
                                    options={villages.map((v) => ({
                                        value: String(v.id),
                                        label: v.name,
                                    }))}
                                    value={form.data.village}
                                    onValueChange={(value) =>
                                        form.setData('village', value)
                                    }
                                    disabled={!form.data.district}
                                    loading={loadingVillages}
                                    placeholder={
                                        !form.data.district
                                            ? 'Pilih kecamatan terlebih dahulu'
                                            : 'Pilih kelurahan/desa'
                                    }
                                    searchPlaceholder="Cari kelurahan/desa..."
                                    error={form.errors.village}
                                />
                            </div>
                        </div>

                        {/* Penanggung Jawab */}
                        <div className="grid gap-4 md:grid-cols-2">
                            <div className="space-y-2">
                                <Label htmlFor="referred_by">
                                    Penanggung Jawab (Staff)
                                </Label>
                                <SearchableSelect
                                    options={(users || []).map((u) => ({
                                        value: String(u.id),
                                        label: u.name,
                                    }))}
                                    value={
                                        form.data.referred_by
                                            ? String(form.data.referred_by)
                                            : ''
                                    }
                                    onValueChange={(value) =>
                                        form.setData('referred_by', value)
                                    }
                                    placeholder="Pilih staff penanggung jawab (opsional)"
                                    searchPlaceholder="Cari nama staff..."
                                    error={form.errors.referred_by}
                                />
                                <p className="text-xs text-muted-foreground">
                                    Biarkan kosong jika nasabah datang dengan
                                    sendirinya (tidak ada staff penanggung
                                    jawab).
                                </p>
                            </div>
                        </div>
                    </div>

                    {/* Actions */}
                    <div className="flex items-center justify-end gap-4">
                        <Button
                            type="button"
                            variant="outline"
                            asChild
                            disabled={form.processing}
                        >
                            <Link
                                href={
                                    membersRoutes.show({ member: member.id })
                                        .url
                                }
                            >
                                Batal
                            </Link>
                        </Button>
                        <Button type="submit" disabled={form.processing}>
                            {form.processing
                                ? 'Memperbarui...'
                                : 'Perbarui Anggota'}
                        </Button>
                    </div>
                </form>
            </div>
        </AppLayout>
    );
}
