'use client';

import { useCallback, useEffect, useState } from 'react';
import Swal from 'sweetalert2';
import { RequireRole, useAuth } from '@/lib/auth-context';
import {
  CONTACT_STATUS_BADGES,
  CONTACT_STATUS_LABELS,
  ContactMessage,
  ContactMessageStatus,
  listContactMessages,
  notifyContactMessagesChanged as notifyChanged,
  removeContactMessage,
  updateContactMessageStatus,
} from '@/lib/services/contact-messages';
import {
  EmptyState,
  ErrorAlert,
  Loading,
  Modal,
  PageHeader,
  Pagination,
  formatDateTime,
} from '@/components/app/ui';
import { extractApiError } from '@/lib/api-client';

export default function MensagensPage() {
  return (
    <RequireRole roles={['admin', 'receptionist']}>
      <MessagesView />
    </RequireRole>
  );
}

const PAGE_SIZE = 15;

function MessagesView() {
  const { user } = useAuth();
  const canDelete = user?.role === 'admin';

  const [items, setItems] = useState<ContactMessage[]>([]);
  const [total, setTotal] = useState(0);
  const [totalPages, setTotalPages] = useState(1);
  const [page, setPage] = useState(1);
  const [search, setSearch] = useState('');
  const [term, setTerm] = useState('');
  const [status, setStatus] = useState<ContactMessageStatus | ''>('');
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const [selected, setSelected] = useState<ContactMessage | null>(null);
  const [busy, setBusy] = useState(false);

  const load = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const result = await listContactMessages({
        page,
        limit: PAGE_SIZE,
        search: term || undefined,
        status: status || undefined,
      });
      setItems(result.data);
      setTotal(result.total);
      setTotalPages(Math.max(result.totalPages, 1));
    } catch (err) {
      setError(extractApiError(err));
    } finally {
      setLoading(false);
    }
  }, [page, term, status]);

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

  function handleSearch(e: React.FormEvent) {
    e.preventDefault();
    setPage(1);
    setTerm(search.trim());
  }

  function replaceItem(updated: ContactMessage) {
    setItems((current) =>
      current.map((item) => (item.id === updated.id ? updated : item)),
    );
    setSelected((current) => (current?.id === updated.id ? updated : current));
  }

  async function changeStatus(
    message: ContactMessage,
    next: ContactMessageStatus,
  ): Promise<void> {
    setBusy(true);
    try {
      replaceItem(await updateContactMessageStatus(message.id, next));
      notifyChanged();
    } catch (err) {
      Swal.fire({ icon: 'error', title: 'Erro', text: extractApiError(err) });
    } finally {
      setBusy(false);
    }
  }

  async function openMessage(message: ContactMessage) {
    setSelected(message);
    if (message.status === 'new') {
      await changeStatus(message, 'read');
    }
  }

  async function handleRemove(message: ContactMessage) {
    const confirmation = await Swal.fire({
      icon: 'warning',
      title: 'Excluir mensagem?',
      text: `${message.subject} — ${message.name}`,
      showCancelButton: true,
      confirmButtonText: 'Excluir',
      cancelButtonText: 'Cancelar',
      confirmButtonColor: '#dc3545',
    });
    if (!confirmation.isConfirmed) return;

    try {
      await removeContactMessage(message.id);
      setSelected(null);
      notifyChanged();
      await Swal.fire({
        icon: 'success',
        title: 'Mensagem excluída',
        timer: 1100,
        showConfirmButton: false,
      });
      load();
    } catch (err) {
      Swal.fire({ icon: 'error', title: 'Erro', text: extractApiError(err) });
    }
  }

  const filtered = Boolean(term || status);

  return (
    <>
      <PageHeader
        title="Mensagens"
        subtitle="Contatos recebidos pelo formulário do site"
      />

      <form className="row g-2 mb-3" onSubmit={handleSearch}>
        <div className="col-12 col-md-5">
          <div className="input-group">
            <span className="input-group-text">
              <i className="bi bi-search" />
            </span>
            <input
              className="form-control"
              placeholder="Buscar por nome, e-mail ou assunto"
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              aria-label="Buscar mensagem"
            />
          </div>
        </div>
        <div className="col-8 col-md-3">
          <select
            className="form-select"
            aria-label="Filtrar por status"
            value={status}
            onChange={(e) => {
              setPage(1);
              setStatus(e.target.value as ContactMessageStatus | '');
            }}
          >
            <option value="">Todos os status</option>
            {(Object.keys(CONTACT_STATUS_LABELS) as ContactMessageStatus[]).map(
              (s) => (
                <option key={s} value={s}>
                  {CONTACT_STATUS_LABELS[s]}
                </option>
              ),
            )}
          </select>
        </div>
        <div className="col-auto">
          <button className="btn btn-outline-primary" type="submit">
            Buscar
          </button>
        </div>
      </form>

      {error && <ErrorAlert message={error} onRetry={load} />}

      {loading ? (
        <Loading />
      ) : items.length === 0 ? (
        <EmptyState
          icon="bi-envelope-open"
          title="Nenhuma mensagem encontrada"
          description={
            filtered
              ? 'Ajuste a busca ou o filtro e tente novamente.'
              : 'As mensagens enviadas em /contato aparecem aqui.'
          }
        />
      ) : (
        <div className="card border-0 shadow-sm">
          <div className="table-responsive">
            <table className="table table-hover align-middle mb-0">
              <thead className="table-light">
                <tr>
                  <th scope="col">Status</th>
                  <th scope="col">Remetente</th>
                  <th scope="col">Assunto</th>
                  <th scope="col">Recebida</th>
                  <th scope="col" className="text-end">Ações</th>
                </tr>
              </thead>
              <tbody>
                {items.map((message) => {
                  const isNew = message.status === 'new';
                  return (
                    <tr key={message.id} className={isNew ? 'fw-semibold' : ''}>
                      <td>
                        <span className={`badge ${CONTACT_STATUS_BADGES[message.status]}`}>
                          {CONTACT_STATUS_LABELS[message.status]}
                        </span>
                      </td>
                      <td>
                        <div>{message.name}</div>
                        <small className="text-muted fw-normal">{message.email}</small>
                      </td>
                      <td>
                        <div>{message.subject}</div>
                        <small
                          className="text-muted fw-normal d-inline-block text-truncate"
                          style={{ maxWidth: 320 }}
                        >
                          {message.message}
                        </small>
                      </td>
                      <td className="text-muted fw-normal table-nowrap">
                        {formatDateTime(message.createdAt)}
                      </td>
                      <td className="text-end table-nowrap">
                        <button
                          type="button"
                          className="btn btn-sm btn-outline-primary"
                          onClick={() => openMessage(message)}
                        >
                          Abrir
                        </button>
                        {canDelete && (
                          <button
                            type="button"
                            className="btn btn-sm btn-outline-danger ms-1"
                            aria-label={`Excluir mensagem de ${message.name}`}
                            title="Excluir"
                            onClick={() => handleRemove(message)}
                          >
                            <i className="bi bi-trash" aria-hidden="true" />
                          </button>
                        )}
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
          <div className="card-body pt-0">
            <Pagination
              page={page}
              totalPages={totalPages}
              total={total}
              onChange={setPage}
            />
          </div>
        </div>
      )}

      <Modal
        open={Boolean(selected)}
        title={selected?.subject ?? 'Mensagem'}
        onClose={() => setSelected(null)}
        size="lg"
        busy={busy}
        footer={
          selected && (
            <>
              {canDelete && (
                <button
                  type="button"
                  className="btn btn-outline-danger me-auto"
                  onClick={() => handleRemove(selected)}
                  disabled={busy}
                >
                  <i className="bi bi-trash me-1" aria-hidden="true" />
                  Excluir
                </button>
              )}
              {selected.status === 'answered' ? (
                <button
                  type="button"
                  className="btn btn-outline-secondary"
                  onClick={() => changeStatus(selected, 'read')}
                  disabled={busy}
                >
                  Reabrir
                </button>
              ) : (
                <button
                  type="button"
                  className="btn btn-outline-success"
                  onClick={() => changeStatus(selected, 'answered')}
                  disabled={busy}
                >
                  <i className="bi bi-check2-all me-1" aria-hidden="true" />
                  Marcar como respondida
                </button>
              )}
              <a
                className="btn btn-primary"
                href={`mailto:${selected.email}?subject=${encodeURIComponent(
                  `Re: ${selected.subject}`,
                )}`}
              >
                <i className="bi bi-reply me-1" aria-hidden="true" />
                Responder por e-mail
              </a>
            </>
          )
        }
      >
        {selected && (
          <>
            <dl className="row small mb-3">
              <dt className="col-sm-3 text-muted fw-normal">De</dt>
              <dd className="col-sm-9 fw-semibold">{selected.name}</dd>
              <dt className="col-sm-3 text-muted fw-normal">E-mail</dt>
              <dd className="col-sm-9">{selected.email}</dd>
              <dt className="col-sm-3 text-muted fw-normal">Telefone</dt>
              <dd className="col-sm-9">{selected.phone || '—'}</dd>
              <dt className="col-sm-3 text-muted fw-normal">Recebida em</dt>
              <dd className="col-sm-9">{formatDateTime(selected.createdAt)}</dd>
              <dt className="col-sm-3 text-muted fw-normal">Status</dt>
              <dd className="col-sm-9 mb-0">
                <span className={`badge ${CONTACT_STATUS_BADGES[selected.status]}`}>
                  {CONTACT_STATUS_LABELS[selected.status]}
                </span>
              </dd>
            </dl>
            <div
              className="border rounded bg-light p-3"
              style={{ whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}
            >
              {selected.message}
            </div>
            <p className="small text-muted mt-2 mb-0">
              <i className="bi bi-shield-check me-1" aria-hidden="true" />
              Consentimento LGPD registrado em {formatDateTime(selected.consentAt)}.
            </p>
          </>
        )}
      </Modal>
    </>
  );
}
