'use client';

import { Fragment, useEffect } from 'react';
import Link from 'next/link';

export function PageHeader({
  title,
  subtitle,
  action,
}: {
  title: string;
  subtitle?: string;
  action?: React.ReactNode;
}) {
  return (
    <div className="d-flex flex-wrap justify-content-between align-items-start gap-2 mb-4">
      <div>
        <h1 className="h3 fw-bold mb-1">{title}</h1>
        {subtitle && <p className="text-muted mb-0">{subtitle}</p>}
      </div>
      {action}
    </div>
  );
}

export function Loading({ label = 'Carregando…' }: { label?: string }) {
  return (
    <div className="text-center py-5" role="status" aria-live="polite">
      <span className="spinner-border text-primary" />
      <p className="text-muted mt-3 mb-0">{label}</p>
    </div>
  );
}

export function EmptyState({
  icon = 'bi-inbox',
  title,
  description,
  action,
}: {
  icon?: string;
  title: string;
  description?: string;
  action?: React.ReactNode;
}) {
  return (
    <div className="text-center py-5">
      <i className={`bi ${icon} display-4 text-secondary`} />
      <h2 className="h5 mt-3 mb-1">{title}</h2>
      {description && <p className="text-muted">{description}</p>}
      {action}
    </div>
  );
}

export function ErrorAlert({
  message,
  onRetry,
}: {
  message: string;
  onRetry?: () => void;
}) {
  return (
    <div className="alert alert-danger d-flex align-items-center" role="alert">
      <i className="bi bi-exclamation-triangle-fill me-2" />
      <span className="flex-grow-1">{message}</span>
      {onRetry && (
        <button
          type="button"
          className="btn btn-sm btn-outline-danger ms-2"
          onClick={onRetry}
        >
          Tentar novamente
        </button>
      )}
    </div>
  );
}

export function Pagination({
  page,
  totalPages,
  total,
  onChange,
}: {
  page: number;
  totalPages: number;
  total: number;
  onChange: (page: number) => void;
}) {
  if (total === 0) return null;

  const pages = Array.from({ length: totalPages }, (_, i) => i + 1).filter(
    (p) => p === 1 || p === totalPages || Math.abs(p - page) <= 1,
  );

  return (
    <div className="d-flex flex-wrap justify-content-between align-items-center gap-2 mt-3">
      <small className="text-muted">
        {total} registro{total === 1 ? '' : 's'} · página {page} de {totalPages}
      </small>
      <nav aria-label="Paginação">
        <ul className="pagination pagination-sm mb-0">
          <li className={`page-item ${page <= 1 ? 'disabled' : ''}`}>
            <button
              className="page-link"
              onClick={() => onChange(page - 1)}
              disabled={page <= 1}
            >
              Anterior
            </button>
          </li>
          {pages.map((p, idx) => {
            const prev = pages[idx - 1];
            return (
              <Fragment key={p}>
                {prev && p - prev > 1 && (
                  <li className="page-item disabled">
                    <span className="page-link">…</span>
                  </li>
                )}
                <li className={`page-item ${p === page ? 'active' : ''}`}>
                  <button className="page-link" onClick={() => onChange(p)}>
                    {p}
                  </button>
                </li>
              </Fragment>
            );
          })}
          <li className={`page-item ${page >= totalPages ? 'disabled' : ''}`}>
            <button
              className="page-link"
              onClick={() => onChange(page + 1)}
              disabled={page >= totalPages}
            >
              Próxima
            </button>
          </li>
        </ul>
      </nav>
    </div>
  );
}

/**
 * Modal controlado por React (o projeto carrega apenas o CSS do Bootstrap,
 * sem o bundle JS). Renderiza sobre um backdrop e fecha com Esc/clique fora.
 */
export function Modal({
  open,
  title,
  onClose,
  children,
  footer,
  size = 'md',
  busy = false,
}: {
  open: boolean;
  title: string;
  onClose: () => void;
  children: React.ReactNode;
  footer?: React.ReactNode;
  size?: 'sm' | 'md' | 'lg' | 'xl';
  busy?: boolean;
}) {
  useEffect(() => {
    if (!open) return;
    function handleKey(event: KeyboardEvent) {
      if (event.key === 'Escape' && !busy) onClose();
    }
    document.addEventListener('keydown', handleKey);
    return () => document.removeEventListener('keydown', handleKey);
  }, [open, busy, onClose]);

  if (!open) return null;

  return (
    <>
      <div
        className="modal-backdrop fade show"
        onClick={() => !busy && onClose()}
      />
      <div
        className="modal fade show d-block"
        tabIndex={-1}
        role="dialog"
        aria-modal="true"
        aria-label={title}
      >
        <div className={`modal-dialog modal-dialog-centered modal-${size}`}>
          <div className="modal-content">
            <div className="modal-header">
              <h2 className="modal-title h5 mb-0">{title}</h2>
              <button
                type="button"
                className="btn-close"
                aria-label="Fechar"
                onClick={onClose}
                disabled={busy}
              />
            </div>
            <div className="modal-body">{children}</div>
            {footer && <div className="modal-footer">{footer}</div>}
          </div>
        </div>
      </div>
    </>
  );
}

export function BackLink({ href, label }: { href: string; label: string }) {
  return (
    <Link
      href={href}
      className="btn btn-sm btn-link text-decoration-none ps-0 mb-2"
    >
      <i className="bi bi-arrow-left me-1" />
      {label}
    </Link>
  );
}

export function formatDate(value?: string | null): string {
  if (!value) return '—';
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return '—';
  return date.toLocaleDateString('pt-BR');
}

export function formatDateTime(value?: string | null): string {
  if (!value) return '—';
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return '—';
  return date.toLocaleString('pt-BR');
}

export function formatCpf(cpf?: string | null): string {
  if (!cpf) return '—';
  const digits = cpf.replace(/\D/g, '');
  if (digits.length !== 11) return cpf;
  return digits.replace(/(\d{3})(\d{3})(\d{3})(\d{2})/, '$1.$2.$3-$4');
}

export function formatBytes(bytes: number): string {
  if (!bytes) return '0 B';
  const units = ['B', 'KB', 'MB', 'GB'];
  const i = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), 3);
  return `${(bytes / 1024 ** i).toFixed(i === 0 ? 0 : 1)} ${units[i]}`;
}
