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

interface Props {
    wedding: any;
    vendors: any[];
    bookedVendors: any[];
}

const STATUS_COLORS: Record<string, string> = {
    researching: 'bg-blue-100 text-blue-800',
    contacted: 'bg-yellow-100 text-yellow-800',
    meeting_scheduled: 'bg-purple-100 text-purple-800',
    quote_received: 'bg-orange-100 text-orange-800',
    rejected: 'bg-red-100 text-red-800',
};

const STATUS_KEYS: Record<string, string> = {
    researching: 'vendors.status_researching',
    contacted: 'vendors.status_contacted',
    meeting_scheduled: 'vendors.status_meeting',
    quote_received: 'vendors.status_quote',
    rejected: 'vendors.status_rejected',
    booked: 'vendors.status_booked',
};

export default function Vendors({ wedding, vendors, bookedVendors }: Props) {
    const t = useTranslator();
    const [tab, setTab] = useState<'research' | 'booked'>('research');
    const [showAdd, setShowAdd] = useState(false);
    const [editingId, setEditingId] = useState<string | null>(null);
    const [compareMode, setCompareMode] = useState(false);
    const [selectedIds, setSelectedIds] = useState<string[]>([]);
    const [query, setQuery] = useState('');
    const [statusFilter, setStatusFilter] = useState('all');
    const [sortBy, setSortBy] = useState('name');
    const fmt = makeCurrencyFormatter(wedding?.currency || 'USD');

    const form = useForm({
        category: '', name: '', website: '', phone: '', email: '',
        price_estimate: '', status: 'researching', notes: '', rating: 0,
    });

    // Persist a star rating inline. The update endpoint requires category+name,
    // so send the vendor's current values alongside the new rating.
    function rateVendor(v: any, rating: number) {
        router.patch(`/weddings/${wedding.id}/vendors/${v.id}`, {
            category: v.category ?? '', name: v.name ?? '', website: v.website ?? '',
            phone: v.phone ?? '', email: v.email ?? '',
            price_estimate: v.price_estimate ?? '', status: v.status ?? 'researching',
            notes: v.notes ?? '', rating,
        }, { preserveScroll: true });
    }

    function toggleSelect(id: string) {
        setSelectedIds((ids) => ids.includes(id) ? ids.filter((x) => x !== id) : [...ids, id]);
    }

    const num = (x: any) => (x == null || x === '' ? null : Number(x));

    // Vendors chosen for the side-by-side comparison (from the full list, so a
    // selection survives even when search/filter hides the row).
    const comparing = vendors.filter((v) => selectedIds.includes(v.id));

    // Decision-support signals for the comparison, only meaningful with a spread.
    const cmpPrices = comparing.map((v) => num(v.price_estimate)).filter((x): x is number => x != null);
    const lowestPrice = cmpPrices.length > 1 && Math.min(...cmpPrices) < Math.max(...cmpPrices) ? Math.min(...cmpPrices) : null;
    const cmpRatings = comparing.map((v) => v.rating ?? 0).filter((r) => r > 0);
    const topRating = cmpRatings.length > 1 && Math.min(...cmpRatings) < Math.max(...cmpRatings) ? Math.max(...cmpRatings) : null;
    // A side-by-side only makes sense within one category; flag (don't block) a mix.
    const mixedCategories = new Set(comparing.map((v) => (v.category ?? '').trim().toLowerCase()).filter(Boolean)).size > 1;

    // Research list with search, status filter and sort applied. Sorting copies
    // the array first so the underlying prop is never mutated.
    const displayedVendors = [...vendors]
        .filter((v) => {
            const q = query.trim().toLowerCase();
            const matchesQuery = !q
                || (v.name ?? '').toLowerCase().includes(q)
                || (v.category ?? '').toLowerCase().includes(q);
            const matchesStatus = statusFilter === 'all' || v.status === statusFilter;
            return matchesQuery && matchesStatus;
        })
        .sort((a, b) => {
            if (sortBy === 'rating') return (b.rating ?? 0) - (a.rating ?? 0);
            if (sortBy === 'price_low' || sortBy === 'price_high') {
                const av = num(a.price_estimate), bv = num(b.price_estimate);
                if (av == null) return 1;        // unpriced vendors sink to the bottom
                if (bv == null) return -1;
                return sortBy === 'price_low' ? av - bv : bv - av;
            }
            if (sortBy === 'category') return (a.category ?? '').localeCompare(b.category ?? '');
            return (a.name ?? '').localeCompare(b.name ?? '');
        });

    const bookedForm = useForm({
        category: '', name: '', contact_name: '', phone: '', email: '', website: '',
        total_cost: '', deposit_paid: '', balance_due: '', payment_due_date: '',
        coi_received: false, contract_signed: false, notes: '',
    });

    function startEditResearch(v: any) {
        form.setData({
            category: v.category ?? '', name: v.name ?? '', website: v.website ?? '',
            phone: v.phone ?? '', email: v.email ?? '',
            price_estimate: v.price_estimate ?? '', status: v.status ?? 'researching',
            notes: v.notes ?? '', rating: v.rating ?? 0,
        });
        setEditingId(v.id);
        setShowAdd(true);
    }

    function startEditBooked(v: any) {
        bookedForm.setData({
            category: v.category ?? '', name: v.name ?? '', contact_name: v.contact_name ?? '',
            phone: v.phone ?? '', email: v.email ?? '', website: v.website ?? '',
            total_cost: v.total_cost ?? '', deposit_paid: v.deposit_paid ?? '',
            balance_due: v.balance_due ?? '', payment_due_date: v.payment_due_date ?? '',
            coi_received: !!v.coi_received, contract_signed: !!v.contract_signed,
            notes: v.notes ?? '',
        });
        setEditingId(v.id);
        setShowAdd(true);
    }

    function closeModal() {
        setShowAdd(false);
        setEditingId(null);
        form.reset();
        bookedForm.reset();
    }

    function handleAdd(e: React.FormEvent) {
        e.preventDefault();
        const action = tab === 'research'
            ? form.post(`/weddings/${wedding.id}/vendors`, { onSuccess: () => { form.reset(); setShowAdd(false); }, preserveScroll: true })
            : bookedForm.post(`/weddings/${wedding.id}/booked-vendors`, { onSuccess: () => { bookedForm.reset(); setShowAdd(false); }, preserveScroll: true });
    }

    const totalBooked = bookedVendors.reduce((s, v) => s + Number(v.total_cost ?? 0), 0);
    const totalPaid = bookedVendors.reduce((s, v) => s + Number(v.deposit_paid ?? 0), 0);

    // Export reflects the active tab.
    const exportRows = tab === 'research' ? vendors : bookedVendors;
    const exportColumns = tab === 'research'
        ? [
            { header: t('vendors.name'), value: (v: any) => v.name },
            { header: t('vendors.category'), value: (v: any) => v.category },
            { header: t('vendors.status'), value: (v: any) => STATUS_KEYS[v.status] ? t(STATUS_KEYS[v.status]) : v.status },
            { header: t('vendors.rating'), value: (v: any) => v.rating ?? '' },
            { header: t('vendors.price_estimate'), value: (v: any) => v.price_estimate ?? '' },
            { header: t('vendors.email'), value: (v: any) => v.email },
            { header: t('vendors.phone'), value: (v: any) => v.phone },
            { header: t('vendors.website'), value: (v: any) => v.website },
            { header: t('vendors.notes'), value: (v: any) => v.notes },
        ]
        : [
            { header: t('vendors.name'), value: (v: any) => v.name },
            { header: t('vendors.category'), value: (v: any) => v.category },
            { header: t('vendors.total_cost'), value: (v: any) => v.total_cost ?? '' },
            { header: t('vendors.deposit_paid'), value: (v: any) => v.deposit_paid ?? '' },
            { header: t('vendors.email'), value: (v: any) => v.email },
            { header: t('vendors.phone'), value: (v: any) => v.phone },
            { header: t('vendors.website'), value: (v: any) => v.website },
            { header: t('vendors.notes'), value: (v: any) => v.notes },
        ];

    return (
        <AppLayout wedding={wedding}>
            <div className="max-w-5xl mx-auto px-6 py-8">
                <div className="flex items-center justify-between mb-6">
                    <h1 className="font-serif text-3xl">{t('vendors.title')}</h1>
                    <div className="flex items-center gap-2">
                        {tab === 'research' && vendors.length > 1 && (
                            <button
                                onClick={() => { setCompareMode(m => !m); setSelectedIds([]); }}
                                className={`px-4 py-2 rounded-lg text-sm border transition-colors ${compareMode ? 'border-primary text-primary bg-primary/10' : 'border-border text-muted-foreground hover:text-foreground'}`}
                            >
                                {compareMode ? t('vendors.compare_done') : t('vendors.compare')}
                            </button>
                        )}
                        <ExportMenu filename={`vendors-${tab}`} title={t('vendors.title')} columns={exportColumns} rows={exportRows} />
                        <button onClick={() => setShowAdd(true)} className="bg-primary text-primary-foreground px-4 py-2 rounded-lg text-sm">
                            + {t('vendors.add_vendor')}
                        </button>
                    </div>
                </div>

                {tab === 'booked' && (
                    <div className="grid grid-cols-3 gap-4 mb-6">
                        <div className="bg-card border border-border rounded-lg p-4">
                            <p className="text-xs text-muted-foreground uppercase">{t('vendors.booked')}</p>
                            <p className="text-xl font-semibold">{bookedVendors.length}</p>
                        </div>
                        <div className="bg-card border border-border rounded-lg p-4">
                            <p className="text-xs text-muted-foreground uppercase">{t('vendors.total_cost')}</p>
                            <p className="text-xl font-semibold">{fmt(totalBooked)}</p>
                        </div>
                        <div className="bg-card border border-border rounded-lg p-4">
                            <p className="text-xs text-muted-foreground uppercase">{t('vendors.paid')}</p>
                            <p className="text-xl font-semibold">{fmt(totalPaid)}</p>
                        </div>
                    </div>
                )}

                <div className="flex gap-1 mb-6 border-b border-border">
                    {(['research', 'booked'] as const).map(tabKey => (
                        <button
                            key={tabKey}
                            onClick={() => setTab(tabKey)}
                            className={`px-4 py-2 text-sm capitalize font-medium border-b-2 transition-colors ${tab === tabKey ? 'border-primary text-primary' : 'border-transparent text-muted-foreground'}`}
                        >
                            {tabKey === 'research' ? `${t('vendors.researching')} (${vendors.length})` : `${t('vendors.booked')} (${bookedVendors.length})`}
                        </button>
                    ))}
                </div>

                {tab === 'research' ? (
                    <>
                        {/* Toolbar: search · status filter · sort */}
                        <div className="flex flex-wrap items-center gap-2 mb-4">
                            <input
                                type="search"
                                value={query}
                                onChange={(e) => setQuery(e.target.value)}
                                placeholder={t('vendors.search_placeholder')}
                                className="flex-1 min-w-[180px] border border-border rounded-lg px-3 py-2 text-sm"
                            />
                            <select value={statusFilter} onChange={(e) => setStatusFilter(e.target.value)} className="border border-border rounded-lg px-3 py-2 text-sm">
                                <option value="all">{t('vendors.all_statuses')}</option>
                                <option value="researching">{t('vendors.status_researching')}</option>
                                <option value="contacted">{t('vendors.status_contacted')}</option>
                                <option value="meeting_scheduled">{t('vendors.status_meeting')}</option>
                                <option value="quote_received">{t('vendors.status_quote')}</option>
                                <option value="rejected">{t('vendors.status_rejected')}</option>
                            </select>
                            <select value={sortBy} onChange={(e) => setSortBy(e.target.value)} className="border border-border rounded-lg px-3 py-2 text-sm">
                                <option value="name">{t('vendors.sort_name')}</option>
                                <option value="rating">{t('vendors.sort_rating')}</option>
                                <option value="price_low">{t('vendors.sort_price_low')}</option>
                                <option value="price_high">{t('vendors.sort_price_high')}</option>
                                <option value="category">{t('vendors.sort_category')}</option>
                            </select>
                        </div>

                        {compareMode && (
                            <p className="text-xs text-muted-foreground mb-3">{t('vendors.compare_hint')}</p>
                        )}

                        {/* Comparison stays pinned at the top and updates live as vendors are ticked. */}
                        {compareMode && comparing.length > 0 && (
                            <div className="sticky top-4 z-30 mb-4 border border-border rounded-xl bg-card shadow-lg overflow-hidden">
                                <div className="flex items-center justify-between px-4 py-2.5 border-b border-border bg-muted/40">
                                    <p className="font-medium text-sm">
                                        {t('vendors.comparison')} · {t('vendors.selected_count', { count: comparing.length })}
                                    </p>
                                    <button onClick={() => setSelectedIds([])} className="text-xs text-muted-foreground hover:text-foreground">
                                        {t('vendors.clear')}
                                    </button>
                                </div>
                                {mixedCategories && (
                                    <p className="px-4 py-2 text-xs text-amber-700 bg-amber-50 border-b border-amber-200">
                                        {t('vendors.mixed_categories')}
                                    </p>
                                )}
                                {comparing.length < 2 ? (
                                    <p className="px-4 py-3 text-xs text-muted-foreground">{t('vendors.compare_need_two')}</p>
                                ) : (
                                    <div className="overflow-auto max-h-[45vh]">
                                        <table className="w-full text-sm border-collapse">
                                            <thead>
                                                <tr className="border-b border-border">
                                                    <th className="text-left p-3 font-medium text-muted-foreground align-bottom w-32 sticky left-0 bg-card" />
                                                    {comparing.map(v => (
                                                        <th key={v.id} className="text-left p-3 font-medium min-w-[150px] align-bottom">{v.name}</th>
                                                    ))}
                                                </tr>
                                            </thead>
                                            <tbody>
                                                <CompareRow label={t('vendors.category')} vendors={comparing} render={(v) => v.category || '—'} />
                                                <CompareRow label={t('vendors.status')} vendors={comparing} render={(v) => STATUS_KEYS[v.status] ? t(STATUS_KEYS[v.status]) : (v.status || '—')} />
                                                <CompareRow label={t('vendors.rating')} vendors={comparing} render={(v) => v.rating ? <StarRating value={v.rating} readOnly /> : <span className="text-muted-foreground">{t('vendors.not_rated')}</span>} badge={(v) => topRating != null && (v.rating ?? 0) === topRating ? t('vendors.badge_top_rated') : null} />
                                                <CompareRow label={t('vendors.price_estimate')} vendors={comparing} render={(v) => v.price_estimate ? fmt(Number(v.price_estimate)) : '—'} badge={(v) => lowestPrice != null && num(v.price_estimate) === lowestPrice ? t('vendors.badge_lowest') : null} />
                                                <CompareRow label={t('vendors.email')} vendors={comparing} render={(v) => v.email || '—'} />
                                                <CompareRow label={t('vendors.phone')} vendors={comparing} render={(v) => v.phone || '—'} />
                                                <CompareRow label={t('vendors.website')} vendors={comparing} render={(v) => v.website ? <a href={v.website} target="_blank" rel="noreferrer" className="text-primary hover:underline break-all">{v.website}</a> : '—'} />
                                                <CompareRow label={t('vendors.notes')} vendors={comparing} render={(v) => v.notes || '—'} />
                                            </tbody>
                                        </table>
                                    </div>
                                )}
                            </div>
                        )}

                        <div className="space-y-2">
                            {displayedVendors.map(v => (
                                <div key={v.id} className="bg-card border border-border rounded-lg p-4 flex items-start gap-3">
                                    {compareMode && (
                                        <input
                                            type="checkbox"
                                            checked={selectedIds.includes(v.id)}
                                            onChange={() => toggleSelect(v.id)}
                                            className="mt-1 shrink-0"
                                            aria-label={v.name}
                                        />
                                    )}
                                    <div className="flex-1 min-w-0">
                                        <div className="flex items-center gap-2 mb-1 flex-wrap">
                                            <span className="font-medium">{v.name}</span>
                                            <span className="text-xs text-muted-foreground">{v.category}</span>
                                            <span className={`px-2 py-0.5 rounded-full text-xs ${STATUS_COLORS[v.status] ?? 'bg-muted'}`}>{STATUS_KEYS[v.status] ? t(STATUS_KEYS[v.status]) : v.status}</span>
                                        </div>
                                        <StarRating value={v.rating ?? 0} onChange={(r) => rateVendor(v, r)} />
                                        {v.email && <p className="text-xs text-muted-foreground mt-1">{v.email}</p>}
                                        {v.price_estimate && <p className="text-xs text-muted-foreground">{t('vendors.est', { amount: fmt(Number(v.price_estimate)) })}</p>}
                                    </div>
                                    <div className="flex items-center gap-3 shrink-0">
                                        <button onClick={() => startEditResearch(v)} className="text-primary text-xs">{t('common.edit')}</button>
                                        <button onClick={() => router.delete(`/weddings/${wedding.id}/vendors/${v.id}`, { preserveScroll: true })} className="text-red-500 text-xs">{t('common.remove')}</button>
                                    </div>
                                </div>
                            ))}
                            {vendors.length === 0 && <p className="text-center text-muted-foreground py-12">{t('vendors.no_vendors')}</p>}
                            {vendors.length > 0 && displayedVendors.length === 0 && <p className="text-center text-muted-foreground py-12">{t('vendors.no_matches')}</p>}
                        </div>
                    </>
                ) : (
                    <div className="space-y-2">
                        {bookedVendors.map(v => (
                            <div key={v.id} className="bg-card border border-border rounded-lg p-4">
                                <div className="flex items-start justify-between">
                                    <div>
                                        <span className="font-medium">{v.name}</span>
                                        <span className="text-xs text-muted-foreground ml-2">{v.category}</span>
                                    </div>
                                    <div className="flex items-center gap-4 text-sm">
                                        {v.contract_signed && <span className="text-green-600">✓ Contract</span>}
                                        {v.coi_received && <span className="text-green-600">✓ COI</span>}
                                        <span className="font-medium">{fmt(Number(v.total_cost ?? 0))}</span>
                                        <button onClick={() => startEditBooked(v)} className="text-primary text-xs">{t('common.edit')}</button>
                                        <button onClick={() => router.delete(`/weddings/${wedding.id}/booked-vendors/${v.id}`, { preserveScroll: true })} className="text-red-500 text-xs">{t('common.remove')}</button>
                                    </div>
                                </div>
                            </div>
                        ))}
                        {bookedVendors.length === 0 && <p className="text-center text-muted-foreground py-12">{t('vendors.no_booked')}</p>}
                    </div>
                )}
            </div>

            {showAdd && (
                <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">{editingId ? t('vendors.edit_vendor') : t('vendors.add_vendor')}</h2>
                            <button onClick={closeModal} className="text-muted-foreground">✕</button>
                        </div>
                        {tab === 'research' ? (
                            <form onSubmit={(e) => {
                                e.preventDefault();
                                if (editingId) {
                                    form.patch(`/weddings/${wedding.id}/vendors/${editingId}`, { onSuccess: closeModal, preserveScroll: true });
                                } else {
                                    form.post(`/weddings/${wedding.id}/vendors`, { onSuccess: closeModal, preserveScroll: true });
                                }
                            }} className="space-y-3">
                                <div className="grid grid-cols-2 gap-3">
                                    <div>
                                        <label className="block text-sm font-medium mb-1">{t('vendors.category')} *</label>
                                        <input type="text" value={form.data.category} onChange={e => form.setData('category', e.target.value)} className="w-full border border-border rounded-lg px-3 py-2 text-sm" required />
                                    </div>
                                    <div>
                                        <label className="block text-sm font-medium mb-1">{t('vendors.name')} *</label>
                                        <input type="text" value={form.data.name} onChange={e => form.setData('name', e.target.value)} className="w-full border border-border rounded-lg px-3 py-2 text-sm" required />
                                    </div>
                                </div>
                                <div className="grid grid-cols-2 gap-3">
                                    <div>
                                        <label className="block text-sm font-medium mb-1">{t('vendors.email')}</label>
                                        <input type="email" value={form.data.email} onChange={e => form.setData('email', e.target.value)} className="w-full border border-border rounded-lg px-3 py-2 text-sm" />
                                    </div>
                                    <div>
                                        <label className="block text-sm font-medium mb-1">{t('vendors.price_estimate')}</label>
                                        <input type="number" value={form.data.price_estimate} onChange={e => form.setData('price_estimate', e.target.value)} className="w-full border border-border rounded-lg px-3 py-2 text-sm" />
                                    </div>
                                </div>
                                <div>
                                    <label className="block text-sm font-medium mb-1">{t('vendors.status')}</label>
                                    <select value={form.data.status} onChange={e => form.setData('status', e.target.value)} className="w-full border border-border rounded-lg px-3 py-2 text-sm">
                                        <option value="researching">{t('vendors.status_researching')}</option>
                                        <option value="contacted">{t('vendors.status_contacted')}</option>
                                        <option value="meeting_scheduled">{t('vendors.status_meeting')}</option>
                                        <option value="quote_received">{t('vendors.status_quote')}</option>
                                        <option value="rejected">{t('vendors.status_rejected')}</option>
                                    </select>
                                </div>
                                <div>
                                    <label className="block text-sm font-medium mb-1">{t('vendors.rating')}</label>
                                    <StarRating value={form.data.rating} onChange={(r) => form.setData('rating', r)} />
                                </div>
                                <textarea value={form.data.notes} onChange={e => form.setData('notes', e.target.value)} placeholder={t('vendors.notes_placeholder')} className="w-full border border-border rounded-lg px-3 py-2 text-sm" rows={2} />
                                <div className="flex gap-3">
                                    <button type="button" onClick={closeModal} className="flex-1 border border-border rounded-lg py-2 text-sm">{t('common.cancel')}</button>
                                    <button type="submit" disabled={form.processing} className="flex-1 bg-primary text-primary-foreground rounded-lg py-2 text-sm">{editingId ? t('common.save') : t('common.add')}</button>
                                </div>
                            </form>
                        ) : (
                            <form onSubmit={(e) => {
                                e.preventDefault();
                                if (editingId) {
                                    bookedForm.patch(`/weddings/${wedding.id}/booked-vendors/${editingId}`, { onSuccess: closeModal, preserveScroll: true });
                                } else {
                                    bookedForm.post(`/weddings/${wedding.id}/booked-vendors`, { onSuccess: closeModal, preserveScroll: true });
                                }
                            }} className="space-y-3">
                                <div className="grid grid-cols-2 gap-3">
                                    <div>
                                        <label className="block text-sm font-medium mb-1">{t('vendors.category')} *</label>
                                        <input type="text" value={bookedForm.data.category} onChange={e => bookedForm.setData('category', e.target.value)} className="w-full border border-border rounded-lg px-3 py-2 text-sm" required />
                                    </div>
                                    <div>
                                        <label className="block text-sm font-medium mb-1">{t('vendors.name')} *</label>
                                        <input type="text" value={bookedForm.data.name} onChange={e => bookedForm.setData('name', e.target.value)} className="w-full border border-border rounded-lg px-3 py-2 text-sm" required />
                                    </div>
                                </div>
                                <div className="grid grid-cols-2 gap-3">
                                    <div>
                                        <label className="block text-sm font-medium mb-1">{t('vendors.total_cost')}</label>
                                        <input type="number" value={bookedForm.data.total_cost} onChange={e => bookedForm.setData('total_cost', e.target.value)} className="w-full border border-border rounded-lg px-3 py-2 text-sm" />
                                    </div>
                                    <div>
                                        <label className="block text-sm font-medium mb-1">{t('vendors.deposit_paid')}</label>
                                        <input type="number" value={bookedForm.data.deposit_paid} onChange={e => bookedForm.setData('deposit_paid', e.target.value)} className="w-full border border-border rounded-lg px-3 py-2 text-sm" />
                                    </div>
                                </div>
                                <div className="flex gap-4">
                                    <label className="flex items-center gap-2 text-sm">
                                        <input type="checkbox" checked={bookedForm.data.contract_signed} onChange={e => bookedForm.setData('contract_signed', e.target.checked)} />
                                        Contract Signed
                                    </label>
                                    <label className="flex items-center gap-2 text-sm">
                                        <input type="checkbox" checked={bookedForm.data.coi_received} onChange={e => bookedForm.setData('coi_received', e.target.checked)} />
                                        COI Received
                                    </label>
                                </div>
                                <div className="flex gap-3">
                                    <button type="button" onClick={closeModal} className="flex-1 border border-border rounded-lg py-2 text-sm">{t('common.cancel')}</button>
                                    <button type="submit" disabled={bookedForm.processing} className="flex-1 bg-primary text-primary-foreground rounded-lg py-2 text-sm">{editingId ? t('common.save') : t('common.add')}</button>
                                </div>
                            </form>
                        )}
                    </div>
                </div>
            )}
        </AppLayout>
    );
}

// Five-star rating. Editable by default; click the current value again to clear.
function StarRating({ value, onChange, readOnly }: { value: number; onChange?: (n: number) => void; readOnly?: boolean }) {
    const [hover, setHover] = useState(0);
    const active = hover || value;
    return (
        <div className="inline-flex items-center gap-0.5">
            {[1, 2, 3, 4, 5].map(n => (
                <button
                    key={n}
                    type="button"
                    disabled={readOnly}
                    onClick={() => onChange?.(value === n ? 0 : n)}
                    onMouseEnter={() => !readOnly && setHover(n)}
                    onMouseLeave={() => !readOnly && setHover(0)}
                    className={`text-[15px] leading-none transition-colors ${readOnly ? 'cursor-default' : 'cursor-pointer'} ${n <= active ? 'text-amber-500' : 'text-muted-foreground/35'}`}
                    aria-label={`${n}`}
                >
                    ★
                </button>
            ))}
        </div>
    );
}

// One attribute row in the side-by-side comparison table. An optional `badge`
// marks a "best" cell (e.g. lowest price / top rating) and tints it.
function CompareRow({ label, vendors, render, badge }: { label: string; vendors: any[]; render: (v: any) => React.ReactNode; badge?: (v: any) => string | null }) {
    return (
        <tr className="border-b border-border/60 last:border-0">
            <th className="text-left p-3 font-medium text-muted-foreground align-top whitespace-nowrap">{label}</th>
            {vendors.map(v => {
                const mark = badge?.(v) ?? null;
                return (
                    <td key={v.id} className={`p-3 align-top ${mark ? 'bg-primary/[0.06]' : ''}`}>
                        <span className={mark ? 'font-medium text-foreground' : ''}>{render(v)}</span>
                        {mark && (
                            <span className="ml-2 inline-block text-[10px] font-medium uppercase tracking-wide text-primary align-middle">{mark}</span>
                        )}
                    </td>
                );
            })}
        </tr>
    );
}
