import { registration } from "../../config/registration";
import Link from "next/link";
import { env } from "../../lib/server-env";
import { getAdmin } from "../../lib/admin-auth";
import { applicationStatusLabel } from "../../lib/application-status";
import { signInPath, getSession } from "../../lib/admin-auth";

type Row = {
  id: string;
  public_number: string;
  status: string;
  submitted_at: string;
  full_name: string;
  response_name: string;
  document_count: number;
  pdf_id: string | null;
};
const statuses = [
  "SUBMITTED",
  "UNDER_REVIEW",
  "INCOMPLETE",
  "ADMITTED",
  "WAITLIST",
  "REJECTED",
];

export default async function Administration({
  searchParams,
}: {
  searchParams: Promise<{ q?: string; status?: string; page?: string }>;
}) {
  const user = await getSession();
  if (!user)
    return (
      <main id="conteudo" className="admin-gate">
        <div>
          <p className="eyebrow">Área reservada</p>
          <h1>Gestão de inscrições</h1>
          <p>Inicie sessão para aceder às candidaturas.</p>
          <a className="button" href={signInPath("/administracao")}>
            Iniciar sessão
          </a>
        </div>
      </main>
    );
  const admin = await getAdmin();
  if (!admin)
    return (
      <main id="conteudo" className="admin-gate">
        <div>
          <p className="eyebrow">Acesso restrito</p>
          <h1>Sem autorização.</h1>
          <p>A conta {user.email} não pertence à lista de administradores.</p>
          <form action="/api/admin/logout" method="post">
            <button>Terminar sessão</button>
          </form>
        </div>
      </main>
    );
  const params = await searchParams,
    q = (params.q || "").trim().slice(0, 100),
    status = (params.status || "").trim();
  let sql =
    "SELECT a.id,a.public_number,a.status,a.submitted_at,c.full_name,s.name response_name,(SELECT count(*) FROM documents d WHERE d.application_id=a.id) document_count,(SELECT id FROM generated_files gf WHERE gf.application_id=a.id AND gf.kind='APPLICATION_PDF' ORDER BY gf.created_at DESC LIMIT 1) pdf_id FROM applications a JOIN children c ON c.application_id=a.id JOIN social_responses s ON s.id=a.social_response_id WHERE a.deleted_at IS NULL";
  const bindings: (string | number)[] = [];
  const page = Math.min(
      100000,
      Math.max(1, Math.floor(Number(params.page) || 1)),
    ),
    pageSize = registration.pageSize;
  if (q) {
    sql += " AND (a.public_number LIKE ? OR c.full_name LIKE ?)";
    bindings.push(`%${q}%`, `%${q}%`);
  }
  if (status) {
    sql += " AND a.status=?";
    bindings.push(status);
  }
  const countSql = sql.replace(
    /^SELECT .*? FROM applications a /,
    "SELECT count(*) total FROM applications a ",
  );
  const filtered = await env.DB.prepare(countSql)
    .bind(...bindings)
    .first<{ total: number }>();
  sql += " ORDER BY a.submitted_at DESC,a.id DESC LIMIT ? OFFSET ?";
  bindings.push(pageSize, (page - 1) * pageSize);
  const jobs = await env.DB.prepare(
    "SELECT status,count(*) total FROM outbox_jobs WHERE status!='DONE' GROUP BY status",
  ).all<{ status: string; total: number }>();
  const pageHref = (n: number) =>
    `/administracao?${new URLSearchParams({ q, status, page: String(n) })}`;
  const [result, summary] = await Promise.all([
    env.DB.prepare(sql)
      .bind(...bindings)
      .all<Row>(),
    env.DB.prepare(
      "SELECT count(*) total,sum(CASE WHEN status='SUBMITTED' THEN 1 ELSE 0 END) submitted,sum(CASE WHEN status='UNDER_REVIEW' THEN 1 ELSE 0 END) reviewing,sum(CASE WHEN status='INCOMPLETE' THEN 1 ELSE 0 END) incomplete FROM applications WHERE deleted_at IS NULL",
    ).first<{
      total: number;
      submitted: number;
      reviewing: number;
      incomplete: number;
    }>(),
  ]);
  return (
    <main id="conteudo" className="admin-shell">
      <header className="admin-header">
        <div>
          <p className="eyebrow">Área reservada</p>
          <h1>Inscrições</h1>
        </div>
        <div>
          <Link
            className="button admin-export"
            href="/api/admin/applications/export"
            prefetch={false}
          >
            Exportar CSV
          </Link>
          <span>{admin.displayName}</span>
          <form action="/api/admin/logout" method="post">
            <button>Sair</button>
          </form>
        </div>
      </header>
      <section className="admin-summary">
        <div>
          <strong>{summary?.total || 0}</strong>
          <span>Total</span>
        </div>
        <div>
          <strong>{summary?.submitted || 0}</strong>
          <span>Novas</span>
        </div>
        <div>
          <strong>{summary?.reviewing || 0}</strong>
          <span>Em análise</span>
        </div>
        <div>
          <strong>{summary?.incomplete || 0}</strong>
          <span>Incompletas</span>
        </div>
      </section>
      <section className="admin-toolbar">
        <form>
          <label>
            Pesquisar
            <input name="q" defaultValue={q} placeholder="Nome ou número" />
          </label>
          <label>
            Estado
            <select name="status" defaultValue={status}>
              <option value="">Todos</option>
              {statuses.map((item) => (
                <option key={item} value={item}>
                  {applicationStatusLabel(item)}
                </option>
              ))}
            </select>
          </label>
          <button className="button">Aplicar filtros</button>
        </form>
        <p>
          {filtered?.total || 0} candidatura(s) · página {page}
        </p>
      </section>
      {jobs.results.length > 0 && (
        <aside className="admin-jobs">
          <strong>Processamento de PDF e email</strong>
          <p>
            {jobs.results.map((j) => `${j.status}: ${j.total}`).join(" · ")}
          </p>
          <a href="/administracao/processamento">Consultar trabalhos</a>
        </aside>
      )}
      <section className="admin-table-wrap">
        <table className="admin-table">
          <thead>
            <tr>
              <th>Número</th>
              <th>Criança</th>
              <th>Resposta</th>
              <th>Documentos</th>
              <th>PDF</th>
              <th>Estado</th>
              <th>Recebida</th>
            </tr>
          </thead>
          <tbody>
            {result.results.map((row) => (
              <tr key={row.id}>
                <td>
                  <Link href={`/administracao/candidaturas/${row.id}`}>
                    {row.public_number}
                  </Link>
                </td>
                <td>{row.full_name}</td>
                <td>{row.response_name}</td>
                <td>{row.document_count}</td>
                <td>
                  <a
                    className="admin-pdf-button"
                    href={`/api/admin/applications/${row.id}/pdf`}
                    target="_blank"
                    rel="noreferrer"
                  >
                    {row.pdf_id ? "Abrir PDF" : "Gerar PDF"}
                  </a>
                </td>
                <td>
                  <span
                    className={`status-pill status-${row.status.toLowerCase()}`}
                  >
                    {applicationStatusLabel(row.status)}
                  </span>
                </td>
                <td>
                  {new Intl.DateTimeFormat("pt-PT", {
                    dateStyle: "short",
                    timeStyle: "short",
                  }).format(new Date(row.submitted_at))}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
        {!result.results.length && (
          <div className="admin-empty">Não foram encontradas candidaturas.</div>
        )}
      </section>
      <nav className="pagination" aria-label="Paginação">
        {page > 1 && <Link href={pageHref(page - 1)}>← Anterior</Link>}
        {page * pageSize < (filtered?.total || 0) && (
          <Link href={pageHref(page + 1)}>Seguinte →</Link>
        )}
      </nav>
    </main>
  );
}
