import { useForm, router } from '@inertiajs/react';
import AppLayout from '@/layouts/AppLayout';
import { useState } from 'react';
import { useTranslator } from '@/lib/i18n';
import { ExportMenu } from '@/components/export-menu';

interface Guest {
    id: string;
    first_name: string;
    last_name?: string;
    email?: string;
    phone?: string;
    side?: string;
    party_count: number;
    party_members?: string[] | null;
    rsvp_status: string;
    meal_preference?: string;
    dietary_notes?: string;
    save_the_date_sent: boolean;
    invite_sent: boolean;
    notes?: string;
    extra_events_invited?: string[] | null;
}

interface ExtraEvent {
    key: string;
    name: string;
    date?: string;
    time?: string;
    location?: string;
}

interface Props {
    wedding: any;
    guests: Guest[];
    emailTemplate?: any;
    rsvpSettings?: any;
}

const RSVP_COLORS: Record<string, string> = {
    pending: 'bg-yellow-100 text-yellow-800',
    confirmed: 'bg-green-100 text-green-800',
    declined: 'bg-red-100 text-red-800',
    maybe: 'bg-blue-100 text-blue-800',
};

const RSVP_KEYS: Record<string, string> = {
    pending: 'guests.rsvp_pending', confirmed: 'guests.rsvp_confirmed',
    attending: 'guests.rsvp_attending', declined: 'guests.rsvp_declined', maybe: 'guests.rsvp_maybe',
};
const SIDE_KEYS: Record<string, string> = {
    partner_a: 'guests.side_partner_a', partner_b: 'guests.side_partner_b', both: 'guests.side_both',
};

export default function Guests({ wedding, guests }: Props) {
    const t = useTranslator();
    const [showAdd, setShowAdd] = useState(false);
    const [editGuest, setEditGuest] = useState<Guest | null>(null);
    const [search, setSearch] = useState('');

    const { data, setData, post, processing, errors, reset } = useForm({
        first_name: '', last_name: '', email: '', phone: '',
        side: '', party_count: 1, party_members: [] as string[],
        meal_preference: '', dietary_notes: '', notes: '',
    });

    const editForm = useForm<any>({});

    function handleAdd(e: React.FormEvent) {
        e.preventDefault();
        post(`/weddings/${wedding.id}/guests`, {
            onSuccess: () => { reset(); setShowAdd(false); },
        });
    }

    function handleEdit(e: React.FormEvent) {
        e.preventDefault();
        if (!editGuest) return;
        editForm.patch(`/weddings/${wedding.id}/guests/${editGuest.id}`, {
            onSuccess: () => setEditGuest(null),
        });
    }

    function startEdit(g: Guest) {
        editForm.setData({
            first_name: g.first_name, last_name: g.last_name ?? '',
            email: g.email ?? '', phone: g.phone ?? '', side: g.side ?? '',
            party_count: g.party_count, party_members: g.party_members ?? [],
            rsvp_status: g.rsvp_status,
            meal_preference: g.meal_preference ?? '', dietary_notes: g.dietary_notes ?? '',
            notes: g.notes ?? '',
            extra_events_invited: g.extra_events_invited ?? [],
        } as any);
        setEditGuest(g);
    }

    const extraEvents: ExtraEvent[] = wedding.extra_events ?? [];
    function toggleEventInvite(key: string) {
        const current: string[] = editForm.data.extra_events_invited ?? [];
        const next = current.includes(key)
            ? current.filter((k: string) => k !== key)
            : [...current, key];
        editForm.setData('extra_events_invited', next as any);
    }

    function deleteGuest(g: Guest) {
        if (!confirm(t('guests.remove_confirm'))) return;
        router.delete(`/weddings/${wedding.id}/guests/${g.id}`, { preserveScroll: true });
    }

    function sendSaveTheDate(g: Guest) {
        router.post(`/weddings/${wedding.id}/guests/${g.id}/send-save-the-date`, {}, { preserveScroll: true });
    }

    function sendInvite(g: Guest) {
        router.post(`/weddings/${wedding.id}/guests/${g.id}/send-invite`, {}, { preserveScroll: true });
    }

    const filtered = guests.filter(g => {
        const name = `${g.first_name} ${g.last_name ?? ''}`.toLowerCase();
        return name.includes(search.toLowerCase()) || g.email?.toLowerCase().includes(search.toLowerCase());
    });

    const totalGuests = guests.reduce((s, g) => s + g.party_count, 0);
    const confirmed = guests.filter(g => g.rsvp_status === 'confirmed').reduce((s, g) => s + g.party_count, 0);

    return (
        <AppLayout wedding={wedding}>
            <div className="max-w-5xl mx-auto px-6 py-8">
                <div className="flex items-center justify-between mb-6">
                    <div>
                        <h1 className="font-serif text-3xl">{t('guests.title')}</h1>
                        <p className="text-muted-foreground text-sm mt-1">
                            {totalGuests} total · {confirmed} confirmed
                        </p>
                    </div>
                    <div className="flex gap-2">
                        <button
                            onClick={() => {
                                if (!confirm(`Send the configured Save-the-Date email to ${totalGuests} guests with email addresses?`)) return;
                                router.post(`/weddings/${wedding.id}/guests/send-save-the-dates`, {}, { preserveScroll: true });
                            }}
                            disabled={totalGuests === 0}
                            title={t('guests.bulk_std_help')}
                            className="border border-border px-3 py-2 rounded-lg text-sm hover:bg-muted disabled:opacity-50 disabled:cursor-not-allowed"
                        >
                            Bulk Save-the-Date
                        </button>
                        <button
                            onClick={() => {
                                if (!confirm(`Send the configured Invitation email to ${totalGuests} guests with email addresses?`)) return;
                                router.post(`/weddings/${wedding.id}/guests/send-invites`, {}, { preserveScroll: true });
                            }}
                            disabled={totalGuests === 0}
                            title={t('guests.bulk_invite_help')}
                            className="border border-border px-3 py-2 rounded-lg text-sm hover:bg-muted disabled:opacity-50 disabled:cursor-not-allowed"
                        >
                            Bulk Invite
                        </button>
                        <ExportMenu
                            filename="guests"
                            title={t('guests.title')}
                            rows={guests}
                            columns={[
                                { header: t('guests.col_name'), value: (g: Guest) => `${g.first_name} ${g.last_name ?? ''}`.trim() },
                                { header: t('guests.col_email'), value: (g: Guest) => g.email },
                                { header: t('common.phone'), value: (g: Guest) => g.phone },
                                { header: t('guests.party_count'), value: (g: Guest) => g.party_count },
                                { header: t('guests.side'), value: (g: Guest) => g.side && SIDE_KEYS[g.side] ? t(SIDE_KEYS[g.side]) : (g.side ?? '') },
                                { header: t('guests.rsvp_status'), value: (g: Guest) => RSVP_KEYS[g.rsvp_status] ? t(RSVP_KEYS[g.rsvp_status]) : g.rsvp_status },
                                { header: t('guests.meal_preference'), value: (g: Guest) => g.meal_preference },
                                { header: t('guests.dietary_notes'), value: (g: Guest) => g.dietary_notes },
                            ]}
                        />
                        <button
                            onClick={() => setShowAdd(true)}
                            className="bg-primary text-primary-foreground px-4 py-2 rounded-lg text-sm font-medium"
                        >
                            + {t('guests.add_guest')}
                        </button>
                    </div>
                </div>

                {/* Search */}
                <div className="mb-4">
                    <input
                        type="text"
                        placeholder={t('guests.search')}
                        value={search}
                        onChange={e => setSearch(e.target.value)}
                        className="w-full border border-border rounded-lg px-3 py-2 text-sm"
                    />
                </div>

                {/* Table */}
                {filtered.length === 0 ? (
                    <div className="text-center py-20 text-muted-foreground">
                        <p className="text-4xl mb-2">👥</p>
                        <p>{guests.length === 0 ? t('guests.none_yet') : 'No guests match your search.'}</p>
                    </div>
                ) : (
                    <div className="overflow-x-auto">
                        <table className="w-full text-sm">
                            <thead>
                                <tr className="border-b border-border text-left">
                                    <th className="pb-2 font-medium text-muted-foreground pr-4">{t('guests.col_name')}</th>
                                    <th className="pb-2 font-medium text-muted-foreground pr-4">{t('guests.col_email')}</th>
                                    <th className="pb-2 font-medium text-muted-foreground pr-4">{t('guests.col_party')}</th>
                                    <th className="pb-2 font-medium text-muted-foreground pr-4">{t('guests.col_rsvp')}</th>
                                    <th className="pb-2 font-medium text-muted-foreground pr-4">{t('guests.col_sent')}</th>
                                    <th className="pb-2" />
                                </tr>
                            </thead>
                            <tbody>
                                {filtered.map(g => (
                                    <tr key={g.id} className="border-b border-border/50 hover:bg-muted/30">
                                        <td className="py-3 pr-4 font-medium">{g.first_name} {g.last_name}</td>
                                        <td className="py-3 pr-4 text-muted-foreground">{g.email ?? '—'}</td>
                                        <td className="py-3 pr-4">{g.party_count}</td>
                                        <td className="py-3 pr-4">
                                            <span className={`px-2 py-0.5 rounded-full text-xs font-medium ${RSVP_COLORS[g.rsvp_status] ?? 'bg-muted'}`}>
                                                {g.rsvp_status}
                                            </span>
                                        </td>
                                        <td className="py-3 pr-4 text-xs text-muted-foreground">
                                            {g.save_the_date_sent ? '✓ STD' : ''}{g.invite_sent ? ' ✓ Inv' : ''}
                                        </td>
                                        <td className="py-3">
                                            <div className="flex gap-1">
                                                {g.email && !g.save_the_date_sent && (
                                                    <button onClick={() => sendSaveTheDate(g)} className="text-xs text-primary hover:underline">STD</button>
                                                )}
                                                {g.email && !g.invite_sent && (
                                                    <button onClick={() => sendInvite(g)} className="text-xs text-primary hover:underline ml-2">{t('guests.invite')}</button>
                                                )}
                                                <button onClick={() => startEdit(g)} className="text-xs text-muted-foreground hover:text-foreground ml-2">{t('common.edit')}</button>
                                                <button onClick={() => deleteGuest(g)} className="text-xs text-red-500 hover:underline ml-2">{t('common.delete')}</button>
                                            </div>
                                        </td>
                                    </tr>
                                ))}
                            </tbody>
                        </table>
                    </div>
                )}
            </div>

            {/* Add Modal */}
            {showAdd && (
                <Modal title={t('guests.add_guest')} onClose={() => { setShowAdd(false); reset(); }}>
                    <form onSubmit={handleAdd} className="space-y-3">
                        <div className="grid grid-cols-2 gap-3">
                            <Field label={`${t('guests.first_name')} *`} error={errors.first_name}>
                                <input type="text" value={data.first_name} onChange={e => setData('first_name', e.target.value)} className="input" required />
                            </Field>
                            <Field label={t('guests.last_name')}>
                                <input type="text" value={data.last_name} onChange={e => setData('last_name', e.target.value)} className="input" />
                            </Field>
                        </div>
                        <div className="grid grid-cols-2 gap-3">
                            <Field label="Email">
                                <input type="email" value={data.email} onChange={e => setData('email', e.target.value)} className="input" />
                            </Field>
                            <Field label="Phone">
                                <input type="text" value={data.phone} onChange={e => setData('phone', e.target.value)} className="input" />
                            </Field>
                        </div>
                        <div className="grid grid-cols-2 gap-3">
                            <Field label={t('guests.side')}>
                                <select value={data.side} onChange={e => setData('side', e.target.value)} className="input">
                                    <option value="">—</option>
                                    <option value="partner_a">{t('guests.side_partner_a')}</option>
                                    <option value="partner_b">{t('guests.side_partner_b')}</option>
                                    <option value="both">{t('guests.side_both')}</option>
                                </select>
                            </Field>
                            <Field label={t('guests.party_count')}>
                                <input
                                    type="text"
                                    inputMode="numeric"
                                    pattern="[0-9]*"
                                    value={data.party_count === 0 ? '' : data.party_count}
                                    onChange={e => {
                                        const v = e.target.value.replace(/[^0-9]/g, '');
                                        setData('party_count', v === '' ? 0 : parseInt(v, 10));
                                    }}
                                    onBlur={e => { if (e.target.value === '') setData('party_count', 1); }}
                                    className="input"
                                />
                            </Field>
                        </div>
                        <PartyMembersFields
                            partyCount={data.party_count}
                            members={data.party_members}
                            onChange={(m) => setData('party_members', m)}
                        />
                        <Field label={t('guests.meal_preference')}>
                            <input type="text" value={data.meal_preference} onChange={e => setData('meal_preference', e.target.value)} className="input" />
                        </Field>
                        <Field label={t('guests.dietary_notes')}>
                            <textarea value={data.dietary_notes} onChange={e => setData('dietary_notes', e.target.value)} className="input" rows={2} />
                        </Field>
                        <div className="flex gap-3 pt-2">
                            <button type="button" onClick={() => { setShowAdd(false); reset(); }} className="flex-1 border border-border rounded-lg py-2 text-sm">{t('common.cancel')}</button>
                            <button type="submit" disabled={processing} className="flex-1 bg-primary text-primary-foreground rounded-lg py-2 text-sm disabled:opacity-60">
                                {processing ? 'Adding…' : t('guests.add_guest')}
                            </button>
                        </div>
                    </form>
                </Modal>
            )}

            {/* Edit Modal */}
            {editGuest && (
                <Modal title={t('guests.edit_guest')} onClose={() => setEditGuest(null)}>
                    <form onSubmit={handleEdit} className="space-y-3">
                        <div className="grid grid-cols-2 gap-3">
                            <Field label={`${t('guests.first_name')} *`}>
                                <input type="text" value={editForm.data.first_name} onChange={e => editForm.setData('first_name', e.target.value)} className="input" required />
                            </Field>
                            <Field label={t('guests.last_name')}>
                                <input type="text" value={editForm.data.last_name} onChange={e => editForm.setData('last_name', e.target.value)} className="input" />
                            </Field>
                        </div>
                        <div className="grid grid-cols-2 gap-3">
                            <Field label="Email">
                                <input type="email" value={editForm.data.email} onChange={e => editForm.setData('email', e.target.value)} className="input" />
                            </Field>
                            <Field label={t('guests.rsvp_status')}>
                                <select value={editForm.data.rsvp_status} onChange={e => editForm.setData('rsvp_status', e.target.value)} className="input">
                                    <option value="pending">{t('guests.rsvp_pending')}</option>
                                    <option value="confirmed">{t('guests.rsvp_confirmed')}</option>
                                    <option value="declined">{t('guests.rsvp_declined')}</option>
                                    <option value="maybe">{t('guests.rsvp_maybe')}</option>
                                </select>
                            </Field>
                        </div>
                        <div className="grid grid-cols-2 gap-3">
                            <Field label={t('guests.party_count')}>
                                <input
                                    type="text"
                                    inputMode="numeric"
                                    pattern="[0-9]*"
                                    value={editForm.data.party_count === 0 ? '' : editForm.data.party_count}
                                    onChange={e => {
                                        const v = e.target.value.replace(/[^0-9]/g, '');
                                        editForm.setData('party_count', v === '' ? 0 : parseInt(v, 10));
                                    }}
                                    onBlur={e => { if (e.target.value === '') editForm.setData('party_count', 1); }}
                                    className="input"
                                />
                            </Field>
                            <Field label={t('guests.meal_preference')}>
                                <input type="text" value={editForm.data.meal_preference} onChange={e => editForm.setData('meal_preference', e.target.value)} className="input" />
                            </Field>
                        </div>
                        <PartyMembersFields
                            partyCount={editForm.data.party_count}
                            members={editForm.data.party_members ?? []}
                            onChange={(m) => editForm.setData('party_members', m)}
                        />
                        <Field label={t('guests.dietary_notes')}>
                            <textarea value={editForm.data.dietary_notes} onChange={e => editForm.setData('dietary_notes', e.target.value)} className="input" rows={2} />
                        </Field>
                        {extraEvents.length > 0 && (
                            <Field label="Invited to extra events">
                                <p className="text-xs text-muted-foreground mb-2">
                                    Tap to toggle. Nothing is opt-in by default — click the events this guest is invited to.
                                </p>
                                <div className="flex flex-wrap gap-2">
                                    {extraEvents.map(evt => {
                                        const checked = (editForm.data.extra_events_invited ?? []).includes(evt.key);
                                        return (
                                            <button
                                                type="button"
                                                key={evt.key}
                                                onClick={() => toggleEventInvite(evt.key)}
                                                className={`text-xs px-3 py-1 rounded-full border transition ${
                                                    checked
                                                        ? 'bg-primary text-primary-foreground border-primary'
                                                        : 'bg-card text-muted-foreground border-border hover:border-primary/50'
                                                }`}
                                            >{evt.name}</button>
                                        );
                                    })}
                                </div>
                            </Field>
                        )}
                        <div className="flex gap-3 pt-2">
                            <button type="button" onClick={() => setEditGuest(null)} className="flex-1 border border-border rounded-lg py-2 text-sm">{t('common.cancel')}</button>
                            <button type="submit" disabled={editForm.processing} className="flex-1 bg-primary text-primary-foreground rounded-lg py-2 text-sm disabled:opacity-60">
                                {editForm.processing ? t('common.saving') : t('guests.save_changes')}
                            </button>
                        </div>
                    </form>
                </Modal>
            )}
        </AppLayout>
    );
}

function Modal({ title, children, onClose }: { title: string; children: React.ReactNode; onClose: () => void }) {
    return (
        <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50">
            <div className="bg-card rounded-2xl p-6 w-full max-w-lg shadow-xl max-h-[90vh] overflow-y-auto">
                <div className="flex items-center justify-between mb-4">
                    <h2 className="font-serif text-xl">{title}</h2>
                    <button onClick={onClose} className="text-muted-foreground hover:text-foreground">✕</button>
                </div>
                {children}
            </div>
        </div>
    );
}

function Field({ label, children, error }: { label: string; children: React.ReactNode; error?: string }) {
    return (
        <div>
            <label className="block text-sm font-medium mb-1">{label}</label>
            {children}
            {error && <p className="text-red-500 text-xs mt-1">{error}</p>}
        </div>
    );
}

// #9: When a party has more than one person, let the couple optionally name
// the additional members. Renders party_count - 1 inputs; the names flow
// through to the seating chart's per-person assignment.
function PartyMembersFields({
    partyCount,
    members,
    onChange,
}: {
    partyCount: number;
    members: string[];
    onChange: (members: string[]) => void;
}) {
    const slots = Math.max(0, (Number(partyCount) || 1) - 1);
    if (slots === 0) return null;

    function setAt(i: number, value: string) {
        const next = Array.from({ length: slots }, (_, j) => members[j] ?? '');
        next[i] = value;
        onChange(next);
    }

    return (
        <Field label="Other party members">
            <p className="text-xs text-muted-foreground mb-2">
                Optional — names show when assigning seats. Leave blank to use “Guest 1”, “Guest 2”, etc.
            </p>
            <div className="space-y-1.5">
                {Array.from({ length: slots }, (_, i) => (
                    <input
                        key={i}
                        type="text"
                        value={members[i] ?? ''}
                        onChange={(e) => setAt(i, e.target.value)}
                        placeholder={`Guest ${i + 1} name`}
                        className="input"
                    />
                ))}
            </div>
        </Field>
    );
}
