import type { Metadata } from "next";
import Link from "next/link";
import { redirect } from "next/navigation";
import { Pencil, Plus, Search } from "lucide-react";
import { CheckNowButton } from "@/components/apps/check-now-button";
import { DeleteProjectButton } from "@/components/apps/delete-project-button";
import { ImportAppsButton } from "@/components/apps/import-apps-button";
import { MonitoringToggle } from "@/components/apps/monitoring-toggle";
import { CheckAllButton } from "@/components/dashboard/check-all-button";
import { RunInProgress } from "@/components/dashboard/run-in-progress";
import { StatusFilter } from "@/components/dashboard/status-filter";
import { PageHeader } from "@/components/layout/page-header";
import { ButtonLink } from "@/components/ui/button-link";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { EmptyState } from "@/components/ui/empty-state";
import { Input } from "@/components/ui/input";
import { Pagination } from "@/components/ui/pagination";
import { STATUS_STYLES, StatusBadge } from "@/components/ui/status-badge";
import { STATUS_PARAMS, statusParam } from "@/lib/dashboard-query";
import { formatDateTime, formatResponseTime } from "@/lib/format";
import { displayStatus, type DisplayStatus } from "@/lib/status";
import { canEdit } from "@/lib/auth/roles";
import { requireUser } from "@/server/auth/session";
import { getDashboardSummary } from "@/server/dashboard/service";
import { PROJECTS_PAGE_SIZE, listProjects } from "@/server/projects/service";
import { getActiveRun } from "@/server/scheduler/runs";
import { getMonitoringSettings } from "@/server/settings/service";

export const metadata: Metadata = { title: "Apps" };

type AppsPageProps = {
  searchParams: Promise<{ [key: string]: string | string[] | undefined }>;
};

function first(value: string | string[] | undefined): string {
  return (Array.isArray(value) ? value[0] : value) ?? "";
}

function appsHref({ q, status, page }: { q: string; status: DisplayStatus | null; page: number }): string {
  const params = new URLSearchParams();
  if (status) params.set("status", statusParam(status));
  if (q) params.set("q", q);
  if (page > 1) params.set("page", String(page));
  const query = params.toString();
  return query ? `/apps?${query}` : "/apps";
}

const th = "px-4 py-2.5 text-left text-xs font-medium text-slate-500";
const td = "px-4 py-3 align-middle";

export default async function AppsPage({ searchParams }: AppsPageProps) {
  const editable = canEdit(await requireUser());

  const params = await searchParams;
  const q = first(params.q).trim().slice(0, 100);
  const status = STATUS_PARAMS[first(params.status)] ?? null;
  const page = Math.max(1, Number.parseInt(first(params.page), 10) || 1);
  const current = { q, status, page };

  const [{ projects, total, pageCount }, summary, activeRun, { timezone: tz }] = await Promise.all([
    listProjects({ search: q, status, page }),
    getDashboardSummary(),
    getActiveRun(),
    getMonitoringSettings(),
  ]);
  if (page > pageCount) redirect(appsHref({ ...current, page: pageCount }));

  const addButton = (
    <ButtonLink href="/apps/new">
      <Plus className="size-4" aria-hidden />
      Add App
    </ButtonLink>
  );

  if (summary.total === 0) {
    return (
      <>
        <PageHeader title="Apps" />
        <EmptyState
          title="No applications configured yet."
          description={
            editable
              ? "Add your first application, or import the list from a sheet, to start monitoring."
              : "An administrator has not added any applications yet."
          }
          action={
            editable && (
              <div className="flex items-center gap-2">
                <ImportAppsButton />
                {addButton}
              </div>
            )
          }
        />
      </>
    );
  }

  return (
    <>
      <PageHeader
        title="Apps"
        actions={
          editable && (
            <>
              <ImportAppsButton />
              <CheckAllButton running={activeRun !== null} disabled={summary.total === summary.disabled} />
              {addButton}
            </>
          )
        }
      />

      {activeRun && (
        <RunInProgress
          label={`${activeRun.trigger === "SCHEDULED" ? "Scheduled check" : "Check All"} in progress — started ${formatDateTime(activeRun.startedAt, tz)}. Statuses update as each app finishes.`}
        />
      )}

      <Card className="overflow-hidden">
        <div className="flex flex-wrap items-center justify-between gap-3 border-b border-slate-200 p-3">
          <StatusFilter active={status} summary={summary} hrefFor={(next) => appsHref({ q, status: next, page: 1 })} />

          <form action="/apps" className="flex items-center gap-2" role="search">
            {status && <input type="hidden" name="status" value={statusParam(status)} />}
            <div className="relative w-64 max-w-full">
              <Search className="pointer-events-none absolute top-2.5 left-2.5 size-4 text-slate-400" aria-hidden />
              <Input
                name="q"
                type="search"
                defaultValue={q}
                placeholder="Search by Project Code or Name"
                aria-label="Search by Project Code or Project Name"
                className="pl-8"
              />
            </div>
            <Button type="submit" variant="secondary">
              Search
            </Button>
            {q && (
              <Link href={appsHref({ q: "", status, page: 1 })} className="text-xs font-medium text-slate-600 hover:text-slate-900">
                Clear
              </Link>
            )}
          </form>
        </div>

        {projects.length === 0 ? (
          <p className="px-4 py-12 text-center text-sm text-slate-500">
            {q ? (
              <>
                No applications match <span className="font-medium text-slate-700">“{q}”</span>
                {status ? " in this status." : "."}
              </>
            ) : (
              "No applications match the current filter."
            )}
          </p>
        ) : (
          <div className="overflow-x-auto">
            <table className="w-full min-w-[64rem] border-collapse text-sm whitespace-nowrap">
              <thead className="border-b border-slate-200 bg-slate-50">
                <tr>
                  <th className={th}>Project Code</th>
                  <th className={th}>Project Name</th>
                  <th className={th}>Production Health API URL</th>
                  <th className={th}>Status</th>
                  <th className={th}>Monitoring</th>
                  <th className={`${th} text-right`}>Expected</th>
                  <th className={`${th} text-right`}>Timeout</th>
                  {editable && (
                    <th className={`${th} text-right`}>
                      <span className="sr-only">Actions</span>
                    </th>
                  )}
                </tr>
              </thead>
              <tbody className="divide-y divide-slate-100">
                {projects.map((project) => {
                  const projectStatus = displayStatus(project);
                  const showResult = projectStatus === "SLOW" || projectStatus === "NOT_WORKING";
                  return (
                    <tr key={project.id} className={STATUS_STYLES[projectStatus].row}>
                      <td className={`${td} font-mono text-xs font-medium text-slate-900`}>{project.projectCode}</td>
                      <td className={`${td} font-medium text-slate-900`}>
                        <Link
                          href={`/apps/${project.id}`}
                          className="block max-w-56 truncate text-slate-900 underline-offset-2 hover:underline"
                          title={project.description ?? project.projectName}
                        >
                          {project.projectName}
                        </Link>
                      </td>
                      <td className={`${td} text-slate-600`}>
                        <span className="block max-w-80 truncate font-mono text-xs" title={project.productionUrl}>
                          {project.productionUrl}
                        </span>
                      </td>
                      <td className={td}>
                        <StatusBadge status={projectStatus} />
                        <span
                          className={`mt-1 block max-w-56 truncate text-xs ${projectStatus === "SLOW" ? "text-amber-700" : "text-slate-500"}`}
                          title={project.currentErrorMessage ?? undefined}
                        >
                          {project.lastCheckedAt
                            ? showResult && project.currentErrorMessage
                              ? project.currentErrorMessage
                              : `Checked ${formatDateTime(project.lastCheckedAt, tz)}${
                                  project.currentResponseTimeMs !== null && projectStatus === "WORKING"
                                    ? ` · ${formatResponseTime(project.currentResponseTimeMs)}`
                                    : ""
                                }`
                            : "No checks yet"}
                        </span>
                      </td>
                      <td className={td}>
                        {editable ? (
                          <MonitoringToggle id={project.id} name={project.projectName} enabled={project.monitoringEnabled} />
                        ) : (
                          <span className="text-xs text-slate-600">{project.monitoringEnabled ? "Enabled" : "Disabled"}</span>
                        )}
                      </td>
                      <td className={`${td} text-right tabular-nums text-slate-600`}>{project.expectedHttpStatus}</td>
                      <td className={`${td} text-right tabular-nums text-slate-600`}>{project.timeoutSeconds}s</td>
                      {editable && (
                      <td className={`${td} text-right`}>
                        <div className="flex items-center justify-end gap-1">
                          <CheckNowButton id={project.id} name={project.projectName} disabled={!project.monitoringEnabled} />
                          <Link
                            href={`/apps/${project.id}/edit`}
                            className="inline-flex h-8 items-center gap-2 rounded-md px-3 text-xs font-medium text-slate-600 transition-colors hover:bg-slate-100 hover:text-slate-900"
                          >
                            <Pencil className="size-3.5" aria-hidden />
                            Edit
                          </Link>
                          <DeleteProjectButton id={project.id} code={project.projectCode} name={project.projectName} />
                        </div>
                      </td>
                      )}
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        )}

        <Pagination
          page={page}
          pageCount={pageCount}
          total={total}
          pageSize={PROJECTS_PAGE_SIZE}
          hrefFor={(p) => appsHref({ ...current, page: p })}
        />
      </Card>
    </>
  );
}
