'use client';

import { useEffect, useState, FormEvent, useMemo } from 'react';
import Header from '@/components/header';
import Modal from '@/components/modal';
import api from '@/lib/api';
import { Charge, Client } from '@/types';

const STATUS_LABELS: Record<string, string> = {
  pending:   'Pendente',
  paid:      'Pago',
  overdue:   'Vencido',
  cancelled: 'Cancelado',
};
const STATUS_COLORS: Record<string, string> = {
  pending:   'bg-yellow-100 text-yellow-700',
  paid:      'bg-green-100 text-green-700',
  overdue:   'bg-red-100 text-red-700',
  cancelled: 'bg-[#EAE4D9] text-[#0E0F12]/60',
};
const METHOD_LABELS: Record<string, string> = {
  pix:         'PIX',
  boleto:      'Boleto',
  credit_card: 'Cartão',
  manual:      'Manual',
  transfer:    'Transferência',
};

type BulkRow = { clientId: string; name: string; status: 'pending' | 'creating' | 'done' | 'error'; error?: string };

const EMPTY_NEW = { description: '', amount: '', discount: '', dueDate: '' };
const EMPTY_PAY = { amountPaid: '', paymentMethod: 'pix', paymentReference: '', paymentNotes: '', paidAt: '' };

export default function CobrancasPage() {
  const [items, setItems]     = useState<Charge[]>([]);
  const [clients, setClients] = useState<Client[]>([]);
  const [loading, setLoading] = useState(true);

  // ── Modal: nova cobrança ──────────────────────────────────────────────────
  const [openNew, setOpenNew]   = useState(false);
  const [form, setForm]         = useState(EMPTY_NEW);
  const [search, setSearch]     = useState('');
  const [selected, setSelected] = useState<Set<string>>(new Set());
  const [bulkRows, setBulkRows] = useState<BulkRow[] | null>(null);
  const [running, setRunning]   = useState(false);

  // ── Modal: baixa manual ───────────────────────────────────────────────────
  const [payCharge, setPayCharge]   = useState<Charge | null>(null);
  const [payForm, setPayForm]       = useState(EMPTY_PAY);
  const [payLoading, setPayLoading] = useState(false);
  const [payError, setPayError]     = useState('');

  // ── Modal: exibir PIX ─────────────────────────────────────────────────────
  const [pixCharge, setPixCharge] = useState<Charge | null>(null);
  const [pixCopied, setPixCopied] = useState(false);

  // ── Geração de título (PIX) ───────────────────────────────────────────────
  const [genLoading, setGenLoading] = useState<Record<string, boolean>>({});

  function loadCharges() {
    return api.get('/charges').then((r) => setItems(r.data.data ?? r.data));
  }

  useEffect(() => {
    Promise.allSettled([
      loadCharges(),
      api.get('/clients').then((r) => setClients(r.data.data ?? r.data)),
    ]).finally(() => setLoading(false));
  }, []);

  // ── Nova cobrança ─────────────────────────────────────────────────────────
  function openNewModal() {
    setForm(EMPTY_NEW);
    setSearch('');
    setSelected(new Set());
    setBulkRows(null);
    setRunning(false);
    setOpenNew(true);
  }

  function toggleClient(id: string) {
    setSelected((prev) => {
      const next = new Set(prev);
      next.has(id) ? next.delete(id) : next.add(id);
      return next;
    });
  }

  function toggleAll(filtered: Client[]) {
    const ids = filtered.map((c) => c.id);
    const allSel = ids.every((id) => selected.has(id));
    setSelected((prev) => {
      const next = new Set(prev);
      allSel ? ids.forEach((id) => next.delete(id)) : ids.forEach((id) => next.add(id));
      return next;
    });
  }

  const filteredClients = useMemo(
    () => clients.filter((c) => c.name.toLowerCase().includes(search.toLowerCase())),
    [clients, search],
  );
  const allFilteredSelected = filteredClients.length > 0 && filteredClients.every((c) => selected.has(c.id));
  const done    = bulkRows?.filter((r) => r.status === 'done').length ?? 0;
  const errors  = bulkRows?.filter((r) => r.status === 'error').length ?? 0;
  const allDone = bulkRows?.every((r) => r.status === 'done' || r.status === 'error') ?? false;

  async function handleSubmitNew(e: FormEvent) {
    e.preventDefault();
    if (selected.size === 0) return;
    const rows: BulkRow[] = [...selected].map((id) => ({
      clientId: id,
      name: clients.find((c) => c.id === id)?.name ?? id,
      status: 'pending',
    }));
    setBulkRows(rows);
    setRunning(true);
    for (let i = 0; i < rows.length; i++) {
      setBulkRows((prev) => prev!.map((r, j) => j === i ? { ...r, status: 'creating' } : r));
      try {
        const payload: Record<string, unknown> = {
          clientId:    rows[i].clientId,
          description: form.description,
          amount:      Number(form.amount),
          dueDate:     form.dueDate,
        };
        if (form.discount) payload.discount = Number(form.discount);
        await api.post('/charges', payload);
        setBulkRows((prev) => prev!.map((r, j) => j === i ? { ...r, status: 'done' } : r));
      } catch (err: any) {
        const msg = err.response?.data?.message ?? 'Erro';
        setBulkRows((prev) => prev!.map((r, j) => j === i ? { ...r, status: 'error', error: msg } : r));
      }
    }
    setRunning(false);
    await loadCharges();
  }

  // ── Baixa manual ──────────────────────────────────────────────────────────
  function openPayModal(charge: Charge) {
    setPayCharge(charge);
    setPayForm({ ...EMPTY_PAY, amountPaid: String(Number(charge.amount).toFixed(2)) });
    setPayError('');
  }

  async function handlePay(e: FormEvent) {
    e.preventDefault();
    if (!payCharge) return;
    setPayLoading(true);
    setPayError('');
    try {
      await api.patch(`/charges/${payCharge.id}/pay`, {
        amountPaid:       Number(payForm.amountPaid),
        paymentMethod:    payForm.paymentMethod,
        paymentReference: payForm.paymentReference || undefined,
        paymentNotes:     payForm.paymentNotes || undefined,
        paidAt:           payForm.paidAt ? new Date(payForm.paidAt).toISOString() : undefined,
      });
      await loadCharges();
      setPayCharge(null);
    } catch (err: any) {
      setPayError(err.response?.data?.message ?? 'Erro ao registrar pagamento');
    } finally {
      setPayLoading(false);
    }
  }

  // ── Geração de PIX ────────────────────────────────────────────────────────
  async function handleGeneratePix(charge: Charge) {
    setGenLoading((p) => ({ ...p, [charge.id]: true }));
    try {
      const { data } = await api.post(`/charges/${charge.id}/payment-link`, { method: 'pix' });
      const updated = { ...charge, ...data };
      setItems((prev) => prev.map((c) => c.id === charge.id ? updated : c));
      setPixCharge(updated);
    } catch (err: any) {
      const msg = err.response?.data?.message ?? 'Erro ao gerar PIX';
      alert(msg);
    } finally {
      setGenLoading((p) => ({ ...p, [charge.id]: false }));
    }
  }

  async function handleCopyPix(text: string) {
    try {
      await navigator.clipboard.writeText(text);
    } catch {
      const el = document.createElement('textarea');
      el.value = text;
      document.body.appendChild(el);
      el.select();
      document.execCommand('copy');
      document.body.removeChild(el);
    }
    setPixCopied(true);
    setTimeout(() => setPixCopied(false), 2000);
  }

  const fmtBRL  = (v: number) =>
    `R$ ${Number(v).toLocaleString('pt-BR', { minimumFractionDigits: 2 })}`;
  const fmtDate = (d: string) =>
    new Date(d + 'T00:00:00').toLocaleDateString('pt-BR');
  const isActionable = (c: Charge) => c.status === 'pending' || c.status === 'overdue';

  return (
    <>
      <Header
        title="Cobranças"
        subtitle="Controle de cobranças e pagamentos"
        action={<button className="btn-primary" onClick={openNewModal}>+ Nova cobrança</button>}
      />

      <div className="bg-white rounded-xl border border-[#EAE4D9] overflow-x-auto">
        {loading ? (
          <p className="p-6 text-sm text-[#0E0F12]/50">Carregando...</p>
        ) : items.length === 0 ? (
          <p className="p-6 text-sm text-[#0E0F12]/50">Nenhuma cobrança criada ainda.</p>
        ) : (
          <table className="w-full text-sm">
            <thead className="bg-[#FAF7F2] border-b border-[#EAE4D9]">
              <tr>
                <th className="text-left px-6 py-3 font-medium text-[#0E0F12]/60">Número</th>
                <th className="text-left px-6 py-3 font-medium text-[#0E0F12]/60">Descrição</th>
                <th className="text-left px-6 py-3 font-medium text-[#0E0F12]/60">Valor</th>
                <th className="text-left px-6 py-3 font-medium text-[#0E0F12]/60">Vencimento</th>
                <th className="text-left px-6 py-3 font-medium text-[#0E0F12]/60">Status</th>
                <th className="text-left px-6 py-3 font-medium text-[#0E0F12]/60">Ações</th>
              </tr>
            </thead>
            <tbody className="divide-y divide-[#EAE4D9]">
              {items.map((c) => (
                <tr key={c.id} className="hover:bg-[#FAF7F2]">
                  <td className="px-6 py-3 font-medium text-[#0E0F12]">{c.number}</td>
                  <td className="px-6 py-3 text-[#0E0F12]/60 max-w-xs truncate">{c.description ?? '—'}</td>
                  <td className="px-6 py-3 text-[#0E0F12]">{fmtBRL(c.amount)}</td>
                  <td className="px-6 py-3 text-[#0E0F12]/50">{fmtDate(c.dueDate)}</td>
                  <td className="px-6 py-3">
                    <span className={`px-2 py-0.5 rounded-full text-xs font-medium ${STATUS_COLORS[c.status] ?? 'bg-[#EAE4D9] text-[#0E0F12]/60'}`}>
                      {STATUS_LABELS[c.status] ?? c.status}
                    </span>
                  </td>
                  <td className="px-6 py-3">
                    {c.status === 'paid' ? (
                      <span className="text-xs text-[#0E0F12]/40">
                        {c.paidAt ? new Date(c.paidAt).toLocaleDateString('pt-BR') : '—'}
                        {c.paymentMethod && ` · ${METHOD_LABELS[c.paymentMethod] ?? c.paymentMethod}`}
                      </span>
                    ) : isActionable(c) ? (
                      <div className="flex items-center gap-2 flex-wrap">
                        {c.pixCopyPaste ? (
                          <button
                            className="text-xs px-2 py-1 rounded bg-teal-50 text-teal-700 hover:bg-teal-100 font-medium"
                            onClick={() => { setPixCharge(c); setPixCopied(false); }}
                          >
                            Ver PIX
                          </button>
                        ) : (
                          <button
                            className="text-xs px-2 py-1 rounded bg-teal-50 text-teal-700 hover:bg-teal-100 font-medium disabled:opacity-50"
                            disabled={!!genLoading[c.id]}
                            onClick={() => handleGeneratePix(c)}
                          >
                            {genLoading[c.id] ? '...' : 'Gerar PIX'}
                          </button>
                        )}
                        {c.boletoUrl && (
                          <a
                            href={c.boletoUrl}
                            target="_blank"
                            rel="noopener noreferrer"
                            className="text-xs px-2 py-1 rounded bg-blue-50 text-blue-700 hover:bg-blue-100 font-medium"
                          >
                            Boleto
                          </a>
                        )}
                        <button
                          className="text-xs px-2 py-1 rounded bg-green-50 text-green-700 hover:bg-green-100 font-medium"
                          onClick={() => openPayModal(c)}
                        >
                          Pagar
                        </button>
                      </div>
                    ) : null}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>

      {/* ── Modal: nova cobrança ─────────────────────────────────────────────── */}
      <Modal open={openNew} onClose={() => { if (!running) setOpenNew(false); }} title="Nova cobrança" wide>
        {!bulkRows ? (
          <form onSubmit={handleSubmitNew} className="space-y-4">
            <div>
              <label className="block text-sm font-medium text-[#0E0F12] mb-1">
                Descrição <span className="text-red-500">*</span>
              </label>
              <input
                className="input"
                required
                value={form.description}
                onChange={(e) => setForm((p) => ({ ...p, description: e.target.value }))}
                placeholder="Ex: Mensalidade Maio/2025"
              />
            </div>
            <div className="grid grid-cols-2 gap-4">
              <div>
                <label className="block text-sm font-medium text-[#0E0F12] mb-1">
                  Valor (R$) <span className="text-red-500">*</span>
                </label>
                <input
                  className="input"
                  type="number"
                  required
                  min="0"
                  step="0.01"
                  value={form.amount}
                  onChange={(e) => setForm((p) => ({ ...p, amount: e.target.value }))}
                  placeholder="0,00"
                />
              </div>
              <div>
                <label className="block text-sm font-medium text-[#0E0F12] mb-1">
                  Vencimento <span className="text-red-500">*</span>
                </label>
                <input
                  className="input"
                  type="date"
                  required
                  value={form.dueDate}
                  onChange={(e) => setForm((p) => ({ ...p, dueDate: e.target.value }))}
                />
              </div>
            </div>
            <div>
              <label className="block text-sm font-medium text-[#0E0F12] mb-1">Desconto (R$)</label>
              <input
                className="input"
                type="number"
                min="0"
                step="0.01"
                value={form.discount}
                onChange={(e) => setForm((p) => ({ ...p, discount: e.target.value }))}
                placeholder="0,00"
              />
            </div>
            <div>
              <div className="flex items-center justify-between mb-1">
                <label className="text-sm font-medium text-[#0E0F12]">
                  Clientes <span className="text-red-500">*</span>
                  {selected.size > 0 && (
                    <span className="ml-2 text-xs font-normal text-[#B7895A]">
                      {selected.size} selecionado{selected.size !== 1 ? 's' : ''}
                    </span>
                  )}
                </label>
                {filteredClients.length > 0 && (
                  <button
                    type="button"
                    onClick={() => toggleAll(filteredClients)}
                    className="text-xs text-[#B7895A] hover:text-[#9E7248]"
                  >
                    {allFilteredSelected ? 'Desmarcar todos' : 'Selecionar todos'}
                  </button>
                )}
              </div>
              <input
                className="input mb-2"
                placeholder="Buscar cliente..."
                value={search}
                onChange={(e) => setSearch(e.target.value)}
              />
              <div className="border border-[#EAE4D9] rounded-lg overflow-y-auto max-h-48 divide-y divide-[#EAE4D9]">
                {filteredClients.length === 0 ? (
                  <p className="px-4 py-3 text-sm text-[#0E0F12]/40">Nenhum cliente encontrado.</p>
                ) : (
                  filteredClients.map((cl) => (
                    <label key={cl.id} className="flex items-center gap-3 px-4 py-2.5 hover:bg-[#FAF7F2] cursor-pointer">
                      <input
                        type="checkbox"
                        className="h-4 w-4 rounded border-[#EAE4D9] accent-[#B7895A]"
                        checked={selected.has(cl.id)}
                        onChange={() => toggleClient(cl.id)}
                      />
                      <span className="text-sm text-[#0E0F12]">{cl.name}</span>
                      {cl.document && (
                        <span className="text-xs text-[#0E0F12]/40 font-mono ml-auto">{cl.document}</span>
                      )}
                    </label>
                  ))
                )}
              </div>
            </div>
            <div className="flex justify-end gap-3 pt-2">
              <button type="button" className="btn-secondary" onClick={() => setOpenNew(false)}>Cancelar</button>
              <button type="submit" className="btn-primary" disabled={selected.size === 0}>
                Criar {selected.size > 1 ? `${selected.size} cobranças` : 'cobrança'}
              </button>
            </div>
          </form>
        ) : (
          <div className="space-y-4">
            <p className="text-sm text-[#0E0F12]/50">
              {allDone
                ? `Concluído: ${done} criada${done !== 1 ? 's' : ''}${errors > 0 ? `, ${errors} erro${errors !== 1 ? 's' : ''}` : ''}.`
                : `Criando cobranças para ${bulkRows.length} cliente${bulkRows.length !== 1 ? 's' : ''}...`}
            </p>
            <div className="border border-[#EAE4D9] rounded-lg overflow-y-auto max-h-64 divide-y divide-[#EAE4D9]">
              {bulkRows.map((r, i) => (
                <div key={i} className="flex items-center justify-between px-4 py-2.5">
                  <span className="text-sm text-[#0E0F12]">{r.name}</span>
                  <span className="text-xs ml-4">
                    {r.status === 'pending'  && <span className="text-[#0E0F12]/40">—</span>}
                    {r.status === 'creating' && <span className="text-[#B7895A]">criando...</span>}
                    {r.status === 'done'     && <span className="text-green-600 font-medium">OK</span>}
                    {r.status === 'error'    && <span className="text-red-600" title={r.error}>Erro</span>}
                  </span>
                </div>
              ))}
            </div>
            {allDone && (
              <div className="flex justify-end pt-1">
                <button className="btn-primary" onClick={() => setOpenNew(false)}>Fechar</button>
              </div>
            )}
          </div>
        )}
      </Modal>

      {/* ── Modal: baixa manual ──────────────────────────────────────────────── */}
      <Modal
        open={!!payCharge}
        onClose={() => { if (!payLoading) setPayCharge(null); }}
        title="Registrar pagamento"
      >
        {payCharge && (
          <form onSubmit={handlePay} className="space-y-4">
            <div className="rounded-lg bg-[#FAF7F2] border border-[#EAE4D9] p-4 text-sm">
              <p className="font-medium text-[#0E0F12]">{payCharge.number}</p>
              {payCharge.description && <p className="text-[#0E0F12]/50 mt-0.5">{payCharge.description}</p>}
              <p className="text-[#0E0F12] font-semibold mt-2">{fmtBRL(Number(payCharge.amount))}</p>
              <p className="text-[#0E0F12]/40 text-xs mt-0.5">Vencimento: {fmtDate(payCharge.dueDate)}</p>
            </div>

            <div>
              <label className="block text-sm font-medium text-[#0E0F12] mb-1">
                Valor pago (R$) <span className="text-red-500">*</span>
              </label>
              <input
                className="input"
                type="number"
                required
                min="0"
                step="0.01"
                value={payForm.amountPaid}
                onChange={(e) => setPayForm((p) => ({ ...p, amountPaid: e.target.value }))}
              />
            </div>

            <div>
              <label className="block text-sm font-medium text-[#0E0F12] mb-1">
                Forma de pagamento <span className="text-red-500">*</span>
              </label>
              <select
                className="input"
                required
                value={payForm.paymentMethod}
                onChange={(e) => setPayForm((p) => ({ ...p, paymentMethod: e.target.value }))}
              >
                <option value="pix">PIX</option>
                <option value="boleto">Boleto</option>
                <option value="credit_card">Cartão de crédito</option>
                <option value="transfer">Transferência</option>
                <option value="manual">Outros</option>
              </select>
            </div>

            <div>
              <label className="block text-sm font-medium text-[#0E0F12] mb-1">Data do pagamento</label>
              <input
                className="input"
                type="datetime-local"
                value={payForm.paidAt}
                onChange={(e) => setPayForm((p) => ({ ...p, paidAt: e.target.value }))}
              />
              <p className="text-xs text-[#0E0F12]/40 mt-1">Deixe em branco para usar a data/hora atual.</p>
            </div>

            <div>
              <label className="block text-sm font-medium text-[#0E0F12] mb-1">Referência / comprovante</label>
              <input
                className="input"
                value={payForm.paymentReference}
                onChange={(e) => setPayForm((p) => ({ ...p, paymentReference: e.target.value }))}
                placeholder="ID de transação, número do comprovante..."
              />
            </div>

            <div>
              <label className="block text-sm font-medium text-[#0E0F12] mb-1">Observações</label>
              <textarea
                className="input"
                rows={2}
                value={payForm.paymentNotes}
                onChange={(e) => setPayForm((p) => ({ ...p, paymentNotes: e.target.value }))}
                placeholder="Informações adicionais..."
              />
            </div>

            {payError && (
              <p className="text-sm text-red-600 bg-red-50 rounded-lg px-3 py-2">{payError}</p>
            )}

            <div className="flex justify-end gap-3 pt-2">
              <button
                type="button"
                className="btn-secondary"
                disabled={payLoading}
                onClick={() => setPayCharge(null)}
              >
                Cancelar
              </button>
              <button type="submit" className="btn-primary" disabled={payLoading}>
                {payLoading ? 'Salvando...' : 'Registrar pagamento'}
              </button>
            </div>
          </form>
        )}
      </Modal>

      {/* ── Modal: PIX Copia e Cola ───────────────────────────────────────────── */}
      <Modal
        open={!!pixCharge}
        onClose={() => { setPixCharge(null); setPixCopied(false); }}
        title="PIX — Copia e Cola"
      >
        {pixCharge?.pixCopyPaste && (
          <div className="space-y-4">
            <div className="rounded-lg bg-[#FAF7F2] border border-[#EAE4D9] p-4 text-sm">
              <p className="font-medium text-[#0E0F12]">{pixCharge.number}</p>
              {pixCharge.description && <p className="text-[#0E0F12]/50 mt-0.5">{pixCharge.description}</p>}
              <p className="text-[#0E0F12] font-semibold mt-2">{fmtBRL(Number(pixCharge.amount))}</p>
            </div>

            <div>
              <label className="block text-xs font-medium text-[#0E0F12]/50 mb-2 uppercase tracking-wide">
                Payload EMV — cole no app do banco
              </label>
              <textarea
                className="input font-mono text-xs resize-none"
                rows={6}
                readOnly
                value={pixCharge.pixCopyPaste}
              />
            </div>

            <button
              type="button"
              className={`w-full py-2.5 rounded-lg text-sm font-medium transition-colors ${
                pixCopied
                  ? 'bg-green-500 text-white'
                  : 'bg-teal-600 hover:bg-teal-700 text-white'
              }`}
              onClick={() => handleCopyPix(pixCharge.pixCopyPaste!)}
            >
              {pixCopied ? 'Copiado!' : 'Copiar código PIX'}
            </button>

            {pixCharge.linkExpiresAt && (
              <p className="text-xs text-[#0E0F12]/40 text-center">
                Expira em {new Date(pixCharge.linkExpiresAt).toLocaleString('pt-BR')}
              </p>
            )}
          </div>
        )}
      </Modal>
    </>
  );
}
