'use client';

import Link from 'next/link';
import { useCallback, useEffect, useState } from 'react';
import Swal from 'sweetalert2';
import { RequireRole } from '@/lib/auth-context';
import {
  Charge,
  CHARGE_STATUS_BADGES,
  CHARGE_STATUS_LABELS,
  listMyCharges,
  ONLINE_METHODS,
  PAYMENT_METHOD_LABELS,
  PaymentMethod,
  payMyCharge,
} from '@/lib/services/finance';
import { EmptyState, ErrorAlert, Loading, PageHeader, formatDate } from '@/components/app/ui';
import { extractApiError } from '@/lib/api-client';
import { formatCents } from '@/lib/money';

export default function PortalFinanceiroPage() {
  return (
    <RequireRole roles={['patient']}>
      <MyFinance />
    </RequireRole>
  );
}

function MyFinance() {
  const [charges, setCharges] = useState<Charge[] | null>(null);
  const [error, setError] = useState<string | null>(null);

  const load = useCallback(async () => {
    setError(null);
    try {
      setCharges(await listMyCharges());
    } catch (err) {
      setError(extractApiError(err));
    }
  }, []);

  useEffect(() => {
    load();
  }, [load]);

  async function handlePay(charge: Charge) {
    // O checkout é do provedor (externo num provedor real): navegação completa
    const pending = charge.payments?.find((p) => p.status === 'pending' && p.checkoutUrl);
    if (pending?.checkoutUrl) {
      window.location.assign(pending.checkoutUrl);
      return;
    }

    const inputOptions = Object.fromEntries(
      ONLINE_METHODS.map((m) => [m, PAYMENT_METHOD_LABELS[m]]),
    );
    const { value: method } = await Swal.fire<PaymentMethod>({
      title: `Pagar ${formatCents(charge.balanceCents)}`,
      text: charge.description,
      input: 'radio',
      inputOptions,
      inputValue: 'pix',
      showCancelButton: true,
      confirmButtonText: 'Continuar',
      cancelButtonText: 'Voltar',
    });
    if (!method) return;

    try {
      const payment = await payMyCharge(charge.id, method);
      if (payment.checkoutUrl) window.location.assign(payment.checkoutUrl);
    } catch (err) {
      Swal.fire({ icon: 'error', title: 'Erro', text: extractApiError(err) });
    }
  }

  if (error) return <ErrorAlert message={error} onRetry={load} />;
  if (!charges) return <Loading />;

  const open = charges.filter((c) => c.status === 'pending' || c.status === 'partially_paid');
  const openTotal = open.reduce((sum, c) => sum + c.balanceCents, 0);
  const receipts = charges
    .flatMap((c) => (c.payments ?? []).map((p) => ({ ...p, description: c.description })))
    .filter((p) => p.receipt);

  return (
    <>
      <PageHeader title="Financeiro" subtitle="Suas parcelas, pagamentos e recibos" />

      {charges.length === 0 ? (
        <EmptyState icon="bi-wallet2" title="Nenhuma cobrança" description="Você não tem valores em aberto." />
      ) : (
        <>
          <div className="row g-3 mb-4">
            <div className="col-sm-6">
              <div className="card border-0 shadow-sm border-start border-4 border-warning">
                <div className="card-body">
                  <div className="small text-muted">Em aberto</div>
                  <div className="fs-4 fw-bold">{formatCents(openTotal)}</div>
                  <small className="text-muted">{open.length} parcela(s)</small>
                </div>
              </div>
            </div>
          </div>

          <div className="card border-0 shadow-sm mb-4">
            <div className="card-header bg-white fw-semibold">Parcelas</div>
            <div className="table-responsive">
              <table className="table align-middle mb-0">
                <thead className="table-light">
                  <tr>
                    <th scope="col">Vencimento</th>
                    <th scope="col">Descrição</th>
                    <th scope="col" className="text-end">Valor</th>
                    <th scope="col">Situação</th>
                    <th scope="col" className="text-end" aria-label="Ações" />
                  </tr>
                </thead>
                <tbody>
                  {charges.map((charge) => {
                    const isOpen = charge.status === 'pending' || charge.status === 'partially_paid';
                    const hasPending = charge.payments?.some((p) => p.status === 'pending');
                    return (
                      <tr key={charge.id}>
                        <td className={`table-nowrap ${charge.isOverdue ? 'text-danger fw-semibold' : ''}`}>
                          {formatDate(`${charge.dueDate}T12:00:00`)}
                        </td>
                        <td>{charge.description}</td>
                        <td className="text-end table-nowrap">
                          {formatCents(charge.amountCents)}
                          {charge.status === 'partially_paid' && (
                            <small className="d-block text-muted">saldo {formatCents(charge.balanceCents)}</small>
                          )}
                        </td>
                        <td>
                          <span className={`badge ${CHARGE_STATUS_BADGES[charge.status]}`}>
                            {CHARGE_STATUS_LABELS[charge.status]}
                          </span>
                          {charge.isOverdue && <span className="badge text-bg-danger ms-1">Vencida</span>}
                        </td>
                        <td className="text-end">
                          {isOpen && (
                            <button className="btn btn-sm btn-primary" onClick={() => handlePay(charge)}>
                              {hasPending ? 'Continuar pagamento' : 'Pagar online'}
                            </button>
                          )}
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          </div>

          <div className="card border-0 shadow-sm">
            <div className="card-header bg-white fw-semibold">Recibos</div>
            {receipts.length === 0 ? (
              <div className="card-body text-muted">Nenhum recibo ainda.</div>
            ) : (
              <ul className="list-group list-group-flush">
                {receipts.map((p) => (
                  <li key={p.id} className="list-group-item d-flex justify-content-between align-items-center">
                    <div>
                      <div className="fw-semibold">
                        Recibo {p.receipt!.number}
                        {p.receipt!.cancelledAt && <span className="badge text-bg-secondary ms-2">Cancelado</span>}
                      </div>
                      <small className="text-muted">
                        {p.description} · {formatDate(p.paidAt)} · {PAYMENT_METHOD_LABELS[p.method]}
                      </small>
                    </div>
                    <div className="text-end">
                      <div className="fw-semibold">{formatCents(p.amountCents)}</div>
                      <Link href={`/portal/financeiro/recibos/${p.receipt!.id}`} className="small">
                        Ver recibo
                      </Link>
                    </div>
                  </li>
                ))}
              </ul>
            )}
          </div>
        </>
      )}
    </>
  );
}
