import { Head, Link, useForm, usePage } 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, toastLoading, toastSuccess } from '@/lib/toast';
import membersRoutes from '@/routes/members';
import type {
    BreadcrumbItem,
    District,
    Province,
    Regency,
    SharedData,
    Village,
} from '@/types';

interface PageProps {
    branches: { id: number; name: string }[];
    provinces: Province[];
    users: { id: number; name: string }[];
}

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

export default function Create({ branches, provinces, users }: PageProps) {
    const { auth } = usePage<SharedData>().props;
    const defaultBranchId = auth.user.branch_id
        ? String(auth.user.branch_id)
        : '';

    const form = useForm({
        id_number: '',
        id_type: 'KTP',
        name: '',
        birth_date: '',
        gender: '',
        phone: '',
        email: '',
        address: '',
        province: '',
        city: '',
        district: '',
        village: '',
        referred_by: '' as string | number,
        branch_id: defaultBranchId,
    });

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

    // Track previous values to prevent redundant fetches
    const prevProvince = useRef(form.data.province);
    const prevCity = useRef(form.data.city);
    const prevDistrict = useRef(form.data.district);

    // Fetch regencies when province changes
    useEffect(() => {
        const province = form.data.province;
        if (province === prevProvince.current) return;
        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([]), 0);
        }
    }, [form.data.province]);

    // Fetch districts when regency changes
    useEffect(() => {
        const city = form.data.city;
        if (city === prevCity.current) return;
        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([]), 0);
        }
    }, [form.data.city]);

    // Fetch villages when district changes
    useEffect(() => {
        const district = form.data.district;
        if (district === prevDistrict.current) return;
        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.post(membersRoutes.store().url, {
            onStart: () => toastLoading('Menambah data anggota....'),
            onSuccess: () => toastSuccess('Anggota berhasil dibuat'),
            onError: () => toastError('Gagal membuat anggota'),
        });
    };

    return (
        <AppLayout breadcrumbs={breadcrumbs}>
            <Head title="Tambah Anggota" />

            <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">
                            Tambah Anggota Baru
                        </h1>
                        <span className="text-sm text-muted-foreground">
                            Isi formulir di bawah untuk mendaftarkan anggota
                            baru.
                        </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>

                            {/* 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 */}
                            {/* 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>
                                {form.errors.referred_by && (
                                    <InputError
                                        message={form.errors.referred_by}
                                    />
                                )}
                            </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.index().url}>Batal</Link>
                        </Button>
                        <Button type="submit" disabled={form.processing}>
                            {form.processing
                                ? 'Menyimpan...'
                                : 'Simpan Nasabah'}
                        </Button>
                    </div>
                </form>
            </div>
        </AppLayout>
    );
}
