import React, { useState, useMemo } from 'react';
import {
    X, Search, Plus, Minus, Trash2, DollarSign, Check,
    ChevronDown, Loader2, Tag, Percent, Banknote
} from 'lucide-react';
import { HybridBackend } from '../services/backend.ts';
import { Paciente, Procedimento, Especialidade, Plano } from '../types.ts';
import { useHybridBackend } from '../hooks/useHybridBackend.ts';
import { useToast } from '../contexts/ToastContext.tsx';

// ─── Tipos internos ────────────────────────────────────────────────────────────
interface LancItem {
    uid: string;
    proc: Procedimento;
    quantidade: number;
    dente: string;
    face: string;
    arco: string;
    observacao: string;
    valorUnit: number;
}

const FACES = ['V', 'L', 'M', 'D', 'O'];
const ARCOS = ['Superior', 'Inferior', 'Ambas'];
const FORMAS_PAG = ['Pix', 'Cartão', 'Dinheiro', 'Boleto'] as const;
const STATUS_LIST = ['Pendente', 'Pago', 'Atrasado'] as const;

const fmt = (v: number) => v.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL' });

function addMonths(date: string, n: number): string {
    const d = new Date(date + 'T12:00:00');
    d.setMonth(d.getMonth() + n);
    return d.toISOString().slice(0, 10);
}

// ─── Chip de procedimento selecionado ─────────────────────────────────────────
const ItemCard: React.FC<{
    item: LancItem;
    onChange: (patch: Partial<LancItem>) => void;
    onRemove: () => void;
}> = ({ item, onChange, onRemove }) => {
    const [open, setOpen] = useState(item.proc.tipo_regiao !== 'GERAL');
    const inp = "border border-gray-200 rounded-lg px-2 py-1.5 text-xs focus:ring-2 focus:ring-teal-100 outline-none w-full";

    return (
        <div className="border border-gray-200 rounded-xl bg-white overflow-hidden">
            <div className="flex items-center gap-2 px-3 py-2.5">
                <div className="flex-1 min-w-0">
                    <p className="text-xs font-black text-gray-800 uppercase truncate">{item.proc.nome}</p>
                    <div className="flex items-center gap-2 mt-0.5">
                        {item.proc.especialidadeNome && (
                            <span className="text-[9px] bg-teal-50 text-teal-600 px-1.5 py-0.5 rounded-full font-bold uppercase">{item.proc.especialidadeNome}</span>
                        )}
                        <span className="text-[10px] font-bold text-green-600">{fmt(item.valorUnit * item.quantidade)}</span>
                        {item.quantidade > 1 && <span className="text-[9px] text-gray-400">{item.quantidade}× {fmt(item.valorUnit)}</span>}
                    </div>
                </div>
                <div className="flex items-center gap-1 flex-shrink-0">
                    <button onClick={() => onChange({ quantidade: Math.max(1, item.quantidade - 1) })} className="w-6 h-6 rounded-full border border-gray-200 flex items-center justify-center hover:bg-gray-100"><Minus size={10} /></button>
                    <span className="w-5 text-center text-xs font-bold">{item.quantidade}</span>
                    <button onClick={() => onChange({ quantidade: item.quantidade + 1 })} className="w-6 h-6 rounded-full border border-gray-200 flex items-center justify-center hover:bg-gray-100"><Plus size={10} /></button>
                </div>
                <button onClick={() => setOpen(o => !o)} className="text-gray-300 hover:text-gray-600 flex-shrink-0">
                    <ChevronDown size={14} className={`transition-transform ${open ? 'rotate-180' : ''}`} />
                </button>
                <button onClick={onRemove} className="text-gray-300 hover:text-red-500 flex-shrink-0"><Trash2 size={13} /></button>
            </div>

            {open && (
                <div className="border-t border-gray-100 bg-gray-50/50 px-3 py-2.5 grid grid-cols-2 gap-2">
                    {item.proc.tipo_regiao === 'DENTE' && (
                        <div>
                            <label className="text-[9px] font-black text-gray-400 uppercase block mb-1">Dente(s)</label>
                            <input value={item.dente} onChange={e => onChange({ dente: e.target.value })} className={inp} placeholder="ex: 16, 21-22" />
                        </div>
                    )}
                    {item.proc.tipo_regiao === 'ARCO' && (
                        <div>
                            <label className="text-[9px] font-black text-gray-400 uppercase block mb-1">Arcada</label>
                            <select value={item.arco} onChange={e => onChange({ arco: e.target.value })} className={inp}>
                                <option value="">— Selecione —</option>
                                {ARCOS.map(a => <option key={a}>{a}</option>)}
                            </select>
                        </div>
                    )}
                    {item.proc.exige_face && (
                        <div>
                            <label className="text-[9px] font-black text-gray-400 uppercase block mb-1">Face(s)</label>
                            <div className="flex gap-1 flex-wrap">
                                {FACES.map(f => (
                                    <button key={f} type="button"
                                        onClick={() => {
                                            const faces = item.face.split('').filter(Boolean);
                                            const next = faces.includes(f) ? faces.filter(x => x !== f) : [...faces, f];
                                            onChange({ face: next.join('') });
                                        }}
                                        className={`w-7 h-7 rounded-lg text-[10px] font-black border transition-colors ${item.face.includes(f) ? 'bg-teal-600 text-white border-teal-600' : 'bg-white text-gray-500 border-gray-200 hover:border-teal-400'}`}>
                                        {f}
                                    </button>
                                ))}
                            </div>
                        </div>
                    )}
                    <div className={item.proc.tipo_regiao !== 'GERAL' || item.proc.exige_face ? '' : 'col-span-2'}>
                        <label className="text-[9px] font-black text-gray-400 uppercase block mb-1">Obs</label>
                        <input value={item.observacao} onChange={e => onChange({ observacao: e.target.value })} className={inp} placeholder="observação opcional" />
                    </div>
                </div>
            )}
        </div>
    );
};

// ─── Modal principal ──────────────────────────────────────────────────────────
export const LancarProcedimentoModal: React.FC<{
    patient: Paciente;
    onClose: () => void;
    onSaved: () => void;
}> = ({ patient, onClose, onSaved }) => {
    const toast = useToast();
    const { data: procsRaw } = useHybridBackend<Procedimento[]>(HybridBackend.getProcedimentos);
    const { data: espsRaw } = useHybridBackend<Especialidade[]>(HybridBackend.getEspecialidades);
    const { data: planosRaw } = useHybridBackend<Plano[]>(HybridBackend.getPlanos);
    const procs = procsRaw ?? [];
    const esps = espsRaw ?? [];
    const planos = planosRaw ?? [];

    const [busca, setBusca] = useState('');
    const [espFiltro, setEspFiltro] = useState('');
    const [items, setItems] = useState<LancItem[]>([]);
    const [saving, setSaving] = useState(false);

    // Pagamento
    const [descTipo, setDescTipo] = useState<'R$' | '%'>('R$');
    const [descValor, setDescValor] = useState('');
    const [entrada, setEntrada] = useState('');
    const [parcelas, setParcelas] = useState(1);
    const [primVenc, setPrimVenc] = useState(new Date().toISOString().slice(0, 10));
    const [formaPag, setFormaPag] = useState<typeof FORMAS_PAG[number]>('Pix');
    const [statusPag, setStatusPag] = useState<typeof STATUS_LIST[number]>('Pendente');

    // Plano vigente do paciente
    const planoVigente = useMemo(() => {
        if (!patient.convenio) return null;
        return planos.find(p => p.nome === patient.convenio) ?? null;
    }, [patient.convenio, planos]);

    const getValorProc = (proc: Procedimento): number => {
        if (planoVigente) {
            const vp = proc.valoresPlanos?.find(v => v.planoId === planoVigente.id);
            if (vp) return vp.valor;
        }
        return proc.valorParticular ?? 0;
    };

    const addProc = (proc: Procedimento) => {
        if (items.some(i => i.proc.id === proc.id)) {
            setItems(prev => prev.map(i => i.proc.id === proc.id ? { ...i, quantidade: i.quantidade + 1 } : i));
            return;
        }
        setItems(prev => [...prev, {
            uid: `${proc.id}_${Date.now()}`,
            proc, quantidade: 1,
            dente: '', face: '', arco: '', observacao: '',
            valorUnit: getValorProc(proc),
        }]);
    };

    const updateItem = (uid: string, patch: Partial<LancItem>) =>
        setItems(prev => prev.map(i => i.uid === uid ? { ...i, ...patch } : i));

    const removeItem = (uid: string) => setItems(prev => prev.filter(i => i.uid !== uid));

    const subtotal = items.reduce((s, i) => s + i.valorUnit * i.quantidade, 0);
    const descNum = parseFloat(descValor) || 0;
    const descReais = descTipo === '%' ? subtotal * descNum / 100 : descNum;
    const entradaNum = parseFloat(entrada) || 0;
    const restante = Math.max(0, subtotal - descReais - entradaNum);
    const valorParcela = parcelas > 0 ? restante / parcelas : 0;

    const procsFiltrados = useMemo(() => {
        return procs.filter(p => {
            if (espFiltro && p.especialidadeId !== espFiltro) return false;
            if (busca && !p.nome.toLowerCase().includes(busca.toLowerCase())) return false;
            return true;
        });
    }, [procs, espFiltro, busca]);

    const procsPorEsp = useMemo(() => {
        const grupos: Record<string, { esp: Especialidade | null; procs: Procedimento[] }> = {};
        procsFiltrados.forEach(p => {
            const key = p.especialidadeId || '__geral';
            if (!grupos[key]) {
                grupos[key] = { esp: esps.find(e => e.id === p.especialidadeId) ?? null, procs: [] };
            }
            grupos[key].procs.push(p);
        });
        return Object.values(grupos).sort((a, b) => (a.esp?.ordem ?? 99) - (b.esp?.ordem ?? 99));
    }, [procsFiltrados, esps]);

    const handleSave = async () => {
        if (items.length === 0) { toast.error('SELECIONE AO MENOS UM PROCEDIMENTO'); return; }
        setSaving(true);
        try {
            const entriesToCreate: any[] = [];
            // FKs de origem (Épico 1): sempre liga ao paciente; procedimento_id só quando há 1 item (não ambíguo)
            const fkBase = {
                paciente_id: patient.id,
                procedimento_id: items.length === 1 ? items[0].proc.id : null,
                origem: 'procedimento',
            };
            const baseDesc = items.map(i => {
                const region = [i.dente, i.arco, i.face].filter(Boolean).join('/');
                return i.proc.nome + (region ? ` (${region})` : '') + (i.quantidade > 1 ? ` x${i.quantidade}` : '');
            }).join(', ');

            if (entradaNum > 0) {
                entriesToCreate.push({
                    id: crypto.randomUUID(),
                    ...fkBase,
                    pacienteNome: patient.nome,
                    descricao: `ENTRADA — ${baseDesc}`,
                    valor: entradaNum,
                    dataVencimento: primVenc,
                    status: 'Pago',
                    formaPagamento: formaPag,
                });
            }

            for (let i = 0; i < parcelas; i++) {
                const label = parcelas > 1 ? ` — ${i + 1}/${parcelas}` : '';
                entriesToCreate.push({
                    id: crypto.randomUUID(),
                    ...fkBase,
                    pacienteNome: patient.nome,
                    descricao: baseDesc + label,
                    valor: parseFloat(valorParcela.toFixed(2)),
                    dataVencimento: entradaNum > 0 ? addMonths(primVenc, i + 1) : addMonths(primVenc, i),
                    status: i === 0 && parcelas === 1 ? statusPag : (i === 0 ? statusPag : 'Pendente'),
                    formaPagamento: formaPag,
                });
            }

            for (const entry of entriesToCreate) {
                await HybridBackend.saveFinanceiro(entry);
            }

            toast.success(`${entriesToCreate.length} LANÇAMENTO(S) GERADO(S) COM SUCESSO!`);
            onSaved();
            onClose();
        } catch { toast.error('ERRO AO SALVAR LANÇAMENTOS'); } finally { setSaving(false); }
    };

    const inp = "border border-gray-200 rounded-lg px-2.5 py-2 text-sm focus:ring-2 focus:ring-teal-100 outline-none w-full bg-white";
    const jaAdicionado = (id: string) => items.some(i => i.proc.id === id);

    return (
        <div className="fixed inset-0 bg-black/50 z-50 flex items-center justify-center backdrop-blur-sm p-0">
            <div className="bg-white shadow-2xl w-full h-dvh md:w-[96vw] md:h-[98vh] rounded-none md:rounded-2xl flex flex-col overflow-hidden animate-in fade-in zoom-in-95 duration-200">

                {/* Header */}
                <div className="flex-shrink-0 px-5 py-4 border-b border-gray-100 flex items-center justify-between bg-gradient-to-r from-emerald-50 to-white">
                    <div className="flex items-center gap-3">
                        <div className="w-9 h-9 bg-emerald-100 rounded-xl flex items-center justify-center">
                            <DollarSign size={18} className="text-emerald-600" />
                        </div>
                        <div>
                            <h2 className="text-sm font-black text-gray-800 uppercase">Lançar Procedimento</h2>
                            <p className="text-[10px] text-gray-400 uppercase font-medium">
                                {patient.nome}
                                {planoVigente && <span className="ml-2 bg-emerald-100 text-emerald-700 px-1.5 py-0.5 rounded-full font-bold">{planoVigente.nome}</span>}
                            </p>
                        </div>
                    </div>
                    <button onClick={onClose} className="text-gray-400 hover:text-gray-600 p-1.5 hover:bg-gray-100 rounded-lg transition-colors"><X size={18} /></button>
                </div>

                {/* Body */}
                <div className="flex flex-1 overflow-hidden">

                    {/* ── Catálogo (esquerda) ── */}
                    <div className="w-72 flex-shrink-0 border-r border-gray-100 flex flex-col bg-gray-50/30">
                        {/* Busca + filtro especialidade */}
                        <div className="p-3 space-y-2 border-b border-gray-100 flex-shrink-0">
                            <div className="relative">
                                <Search size={13} className="absolute left-2.5 top-1/2 -translate-y-1/2 text-gray-400" />
                                <input value={busca} onChange={e => setBusca(e.target.value)} placeholder="Buscar procedimento..."
                                    className="w-full pl-8 pr-3 py-2 border border-gray-200 rounded-lg text-xs focus:ring-2 focus:ring-teal-100 outline-none bg-white" />
                            </div>
                            <div className="flex gap-1 flex-wrap">
                                <button onClick={() => setEspFiltro('')}
                                    className={`text-[10px] font-bold px-2 py-0.5 rounded-full border transition-colors ${!espFiltro ? 'bg-gray-800 text-white border-gray-800' : 'text-gray-500 border-gray-200 hover:bg-gray-100'}`}>
                                    Todas
                                </button>
                                {esps.map(e => (
                                    <button key={e.id} onClick={() => setEspFiltro(f => f === e.id ? '' : e.id)}
                                        className={`text-[10px] font-bold px-2 py-0.5 rounded-full border transition-colors ${espFiltro === e.id ? 'bg-teal-600 text-white border-teal-600' : 'text-gray-500 border-gray-200 hover:bg-gray-100'}`}>
                                        {e.nome}
                                    </button>
                                ))}
                            </div>
                        </div>

                        {/* Lista procedimentos */}
                        <div className="flex-1 overflow-y-auto p-2 space-y-3">
                            {!procsRaw && <div className="flex justify-center pt-8"><Loader2 size={18} className="animate-spin text-gray-300" /></div>}
                            {procsPorEsp.map((grupo, gi) => (
                                <div key={gi}>
                                    {grupo.esp && (
                                        <p className="text-[9px] font-black text-gray-400 uppercase tracking-widest px-2 mb-1">{grupo.esp.nome}</p>
                                    )}
                                    <div className="space-y-0.5">
                                        {grupo.procs.map(p => {
                                            const val = getValorProc(p);
                                            const adicionado = jaAdicionado(p.id);
                                            return (
                                                <button key={p.id} onClick={() => addProc(p)}
                                                    className={`w-full text-left px-2.5 py-2 rounded-lg transition-all flex items-center justify-between gap-2 group ${adicionado ? 'bg-emerald-50 border border-emerald-200' : 'border border-transparent hover:bg-white hover:border-gray-200 hover:shadow-sm'}`}>
                                                    <div className="min-w-0 flex-1">
                                                        <p className={`text-xs font-bold truncate ${adicionado ? 'text-emerald-700' : 'text-gray-700'}`}>{p.nome}</p>
                                                        {p.codigo && <p className="text-[9px] text-gray-400">{p.codigo}</p>}
                                                    </div>
                                                    <div className="flex items-center gap-1.5 flex-shrink-0">
                                                        <span className={`text-[10px] font-black ${adicionado ? 'text-emerald-600' : 'text-green-600'}`}>{fmt(val)}</span>
                                                        {adicionado
                                                            ? <Check size={13} className="text-emerald-500" />
                                                            : <Plus size={13} className="text-gray-300 group-hover:text-teal-500" />}
                                                    </div>
                                                </button>
                                            );
                                        })}
                                    </div>
                                </div>
                            ))}
                            {procsRaw && procsFiltrados.length === 0 && (
                                <p className="text-xs text-gray-400 text-center pt-6">Nenhum procedimento encontrado</p>
                            )}
                        </div>
                    </div>

                    {/* ── Selecionados + pagamento (direita) ── */}
                    <div className="flex-1 flex flex-col overflow-hidden">
                        {/* Items selecionados */}
                        <div className="flex-1 overflow-y-auto p-4 space-y-2">
                            {items.length === 0 ? (
                                <div className="flex flex-col items-center justify-center h-full text-center">
                                    <div className="w-16 h-16 bg-gray-100 rounded-2xl flex items-center justify-center mb-3">
                                        <Tag size={24} className="text-gray-300" />
                                    </div>
                                    <p className="text-sm font-bold text-gray-400">Nenhum procedimento selecionado</p>
                                    <p className="text-xs text-gray-300 mt-1">Clique nos procedimentos ao lado para adicionar</p>
                                </div>
                            ) : (
                                items.map(item => (
                                    <ItemCard key={item.uid} item={item}
                                        onChange={patch => updateItem(item.uid, patch)}
                                        onRemove={() => removeItem(item.uid)} />
                                ))
                            )}
                        </div>

                        {/* ── Painel financeiro ── */}
                        <div className="flex-shrink-0 border-t border-gray-100 bg-gray-50/50 p-4 space-y-3">
                            {/* Subtotal */}
                            <div className="flex items-center justify-between text-sm">
                                <span className="font-bold text-gray-500 uppercase text-xs">Subtotal</span>
                                <span className="font-black text-gray-800 text-base">{fmt(subtotal)}</span>
                            </div>

                            {/* Desconto + entrada */}
                            <div className="grid grid-cols-2 gap-3">
                                <div>
                                    <label className="text-[9px] font-black text-gray-400 uppercase block mb-1">Desconto</label>
                                    <div className="flex gap-1">
                                        <button onClick={() => setDescTipo(t => t === 'R$' ? '%' : 'R$')}
                                            className="px-2 py-2 border border-gray-200 rounded-lg text-[10px] font-black text-gray-500 hover:bg-gray-100 flex-shrink-0 bg-white">
                                            {descTipo === 'R$' ? <Banknote size={12} /> : <Percent size={12} />}
                                        </button>
                                        <input type="number" step="0.01" value={descValor} onChange={e => setDescValor(e.target.value)}
                                            placeholder="0" className={inp + " text-sm"} />
                                    </div>
                                    {descReais > 0 && <p className="text-[10px] text-red-500 mt-0.5">− {fmt(descReais)}</p>}
                                </div>
                                <div>
                                    <label className="text-[9px] font-black text-gray-400 uppercase block mb-1">Entrada (R$)</label>
                                    <input type="number" step="0.01" value={entrada} onChange={e => setEntrada(e.target.value)}
                                        placeholder="0" className={inp} />
                                    {entradaNum > 0 && <p className="text-[10px] text-teal-500 mt-0.5">− {fmt(entradaNum)} (marca como Pago)</p>}
                                </div>
                            </div>

                            {/* Restante + parcelas */}
                            <div className="bg-white rounded-xl border border-gray-200 p-3 space-y-2.5">
                                <div className="flex items-center justify-between">
                                    <span className="text-xs font-black text-gray-500 uppercase">Restante a parcelar</span>
                                    <span className="text-lg font-black text-emerald-600">{fmt(restante)}</span>
                                </div>
                                <div className="grid grid-cols-3 gap-2">
                                    <div>
                                        <label className="text-[9px] font-black text-gray-400 uppercase block mb-1">Parcelas</label>
                                        <select value={parcelas} onChange={e => setParcelas(Number(e.target.value))} className={inp + " text-xs"}>
                                            {Array.from({ length: 48 }, (_, i) => i + 1).map(n => (
                                                <option key={n} value={n}>{n}x — {fmt(restante / n)}</option>
                                            ))}
                                        </select>
                                    </div>
                                    <div>
                                        <label className="text-[9px] font-black text-gray-400 uppercase block mb-1">1ª Parcela</label>
                                        <input type="date" value={primVenc} onChange={e => setPrimVenc(e.target.value)} className={inp + " text-xs"} />
                                    </div>
                                    <div>
                                        <label className="text-[9px] font-black text-gray-400 uppercase block mb-1">Forma</label>
                                        <select value={formaPag} onChange={e => setFormaPag(e.target.value as any)} className={inp + " text-xs"}>
                                            {FORMAS_PAG.map(f => <option key={f}>{f}</option>)}
                                        </select>
                                    </div>
                                </div>
                                {parcelas > 1 && (
                                    <div className="flex items-center justify-between bg-emerald-50 rounded-lg px-3 py-2">
                                        <span className="text-xs font-bold text-emerald-700">{parcelas}x de</span>
                                        <span className="text-sm font-black text-emerald-700">{fmt(valorParcela)}</span>
                                    </div>
                                )}
                                <div className="grid grid-cols-2 gap-2">
                                    <div>
                                        <label className="text-[9px] font-black text-gray-400 uppercase block mb-1">Status 1ª parcela</label>
                                        <select value={statusPag} onChange={e => setStatusPag(e.target.value as any)} className={inp + " text-xs"}>
                                            {STATUS_LIST.map(s => <option key={s}>{s}</option>)}
                                        </select>
                                    </div>
                                    <div className="flex items-end">
                                        <div className="w-full bg-gray-50 border border-gray-100 rounded-lg p-2 text-center">
                                            <p className="text-[9px] font-black text-gray-400 uppercase">Total geral</p>
                                            <p className="text-sm font-black text-gray-800">{fmt(entradaNum + restante)}</p>
                                        </div>
                                    </div>
                                </div>
                            </div>

                            {/* Ações */}
                            <div className="flex gap-2 pt-1">
                                <button onClick={onClose} className="px-5 py-2.5 bg-gray-100 hover:bg-gray-200 text-gray-700 font-bold rounded-lg text-xs uppercase flex-shrink-0">Cancelar</button>
                                <button onClick={handleSave} disabled={items.length === 0 || saving}
                                    className="flex-1 py-2.5 bg-emerald-600 hover:bg-emerald-700 text-white font-black rounded-lg text-xs uppercase disabled:opacity-40 flex items-center justify-center gap-2 transition-colors">
                                    {saving ? <Loader2 size={14} className="animate-spin" /> : <Check size={14} />}
                                    {saving ? 'Salvando...' : `Confirmar ${items.length > 0 ? `— ${fmt(entradaNum + restante)}` : ''}`}
                                </button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    );
};
