import Link from "next/link";
import { redirect } from "next/navigation";
import { Search } from "lucide-react";
import { CheckNowButton } from "@/components/apps/check-now-button";
import { ImportAppsButton } from "@/components/apps/import-apps-button";
import {
  AttentionList,
  CheckTrendChart,
  HealthOverview,
  ResponseTimeCard,
  outageDetail,
  slowDetail,
} from "@/components/dashboard/analytics";
import { CheckAllButton } from "@/components/dashboard/check-all-button";
import { RefreshButton } from "@/components/dashboard/refresh-button";
import { RunInProgress } from "@/components/dashboard/run-in-progress";
import { SortableHeader } from "@/components/dashboard/sortable-header";
import { StatusFilter } from "@/components/dashboard/status-filter";
import { SummaryCards } from "@/components/dashboard/summary-cards";
import { DomainAlert } from "@/components/domains/domain-alert";
import { PageHeader } from "@/components/layout/page-header";
import { Button } from "@/components/ui/button";
import { ButtonLink } from "@/components/ui/button-link";
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 { dashboardHref, parseDashboardQuery, statusParam } from "@/lib/dashboard-query";
import { formatDate, formatDateTime, formatElapsed, formatResponseTime } from "@/lib/format";
import { displayStatus } from "@/lib/status";
import { canEdit } from "@/lib/auth/roles";
import { requireUser } from "@/server/auth/session";
import {
  DASHBOARD_PAGE_SIZE,
  getCheckTrend,
  getDashboardSummary,
  getResponseTimeStats,
  listDashboardRows,
  listOutages,
  listSlowest,
} from "@/server/dashboard/service";
import { listDomainsNeedingAttention } from "@/server/domains/service";
import { getActiveRun } from "@/server/scheduler/runs";
import { getMonitoringSettings } from "@/server/settings/service";

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

const th = "px-4 py-2.5 text-left text-xs font-medium text-slate-500";
const td = "px-4 py-2.5 align-middle";
const dash = <span className="text-slate-300">—</span>;

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

  const query = parseDashboardQuery(await searchParams);
  const settings = await getMonitoringSettings();
  const tz = settings.timezone;
  const [summary, { rows, total, pageCount }, activeRun, trend, responseTimes, outages, slowest, domainAlerts] = await Promise.all([
    getDashboardSummary(),
    listDashboardRows(query),
    getActiveRun(),
    getCheckTrend(tz),
    getResponseTimeStats(),
    listOutages(5),
    listSlowest(5),
    listDomainsNeedingAttention(),
  ]);
  if (query.page > pageCount) redirect(dashboardHref(query, { page: pageCount }));

  if (summary.total === 0) {
    return (
      <>
        <PageHeader title="Dashboard" />
        <SummaryCards summary={summary} active={null} />
        <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 />
                <ButtonLink href="/apps/new">Add App</ButtonLink>
              </div>
            )
          }
        />
      </>
    );
  }

  const neverChecked = summary.lastCheckedAt === null;

  return (
    <>
      <PageHeader
        title="Dashboard"
        actions={
          <>
            <span className="hidden text-xs text-slate-500 sm:inline">
              {summary.lastCheckedAt ? `Latest check ${formatDateTime(summary.lastCheckedAt, tz)}` : "No checks yet"}
            </span>
            <RefreshButton />
            {editable && <CheckAllButton running={activeRun !== null} disabled={summary.total === summary.disabled} />}
          </>
        }
      />

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

      <DomainAlert rows={domainAlerts} />

      <SummaryCards summary={summary} active={query.status} />

      <div className="mb-4 grid gap-3 lg:grid-cols-3">
        <HealthOverview summary={summary} />
        <CheckTrendChart days={trend} timezone={tz} />
        <ResponseTimeCard stats={responseTimes} slowThresholdSeconds={settings.slowThresholdSeconds} />
      </div>

      <div className="mb-4 grid gap-3 lg:grid-cols-2">
        <AttentionList
          title="Needs attention"
          rows={outages}
          empty="No apps are down right now."
          detail={outageDetail}
          tz={tz}
          seeAll={dashboardHref(query, { status: "NOT_WORKING", page: 1 })}
        />
        <AttentionList
          title="Slowest responses"
          rows={slowest}
          empty="No response times recorded yet."
          detail={slowDetail}
          tz={tz}
          seeAll={dashboardHref(query, { status: null, sort: "responseTime", dir: "desc", page: 1 })}
        />
      </div>

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

          <form action="/" className="flex items-center gap-2" role="search">
            {/* Keep the current filter and sort when searching. */}
            {query.status && <input type="hidden" name="status" value={statusParam(query.status)} />}
            {(query.sort !== "status" || query.dir !== "asc") && (
              <>
                <input type="hidden" name="sort" value={query.sort} />
                <input type="hidden" name="dir" value={query.dir} />
              </>
            )}
            <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={query.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>
            {query.q && (
              <Link
                href={dashboardHref(query, { q: "", page: 1 })}
                className="text-xs font-medium text-slate-600 hover:text-slate-900"
              >
                Clear
              </Link>
            )}
          </form>
        </div>

        {neverChecked && (
          <p className="border-b border-slate-200 bg-slate-50 px-4 py-2.5 text-xs text-slate-600">
            No health-check data available yet. The first scheduled check will appear here.
          </p>
        )}

        {rows.length === 0 ? (
          <p className="px-4 py-12 text-center text-sm text-slate-500">No applications match the current filter.</p>
        ) : (
          <div className="overflow-x-auto">
            <table className="w-full min-w-[68rem] border-collapse text-sm whitespace-nowrap">
              <thead className="border-b border-slate-200 bg-slate-50">
                <tr>
                  <SortableHeader label="Project Code" sortKey="code" query={query} />
                  <SortableHeader label="Project Name" sortKey="name" query={query} />
                  <SortableHeader label="Status" sortKey="status" query={query} />
                  <SortableHeader label="Checked At" sortKey="checkedAt" query={query} />
                  <th scope="col" className={`${th} text-right`}>
                    HTTP
                  </th>
                  <SortableHeader label="Response Time" sortKey="responseTime" query={query} align="right" />
                  <th scope="col" className={th}>
                    Error Message
                  </th>
                  <th scope="col" className={th}>
                    Not Working Since
                  </th>
                  {editable && (
                    <th scope="col" className={`${th} text-right`}>
                      <span className="sr-only">Actions</span>
                    </th>
                  )}
                </tr>
              </thead>
              <tbody className="divide-y divide-slate-100">
                {rows.map((row) => {
                  const status = displayStatus(row);
                  // A disabled app shows no check data: its last result is stale by design.
                  const live = status === "WORKING" || status === "SLOW" || status === "NOT_WORKING";
                  const failing = status === "NOT_WORKING";
                  const slow = status === "SLOW";

                  return (
                    <tr key={row.id} className={STATUS_STYLES[status].row}>
                      <td className={`${td} font-mono text-xs font-medium text-slate-900`}>{row.projectCode}</td>
                      <td className={`${td} font-medium`}>
                        <Link
                          href={`/apps/${row.id}`}
                          className="block max-w-56 truncate text-slate-900 underline-offset-2 hover:underline"
                          title={row.projectName}
                        >
                          {row.projectName}
                        </Link>
                      </td>
                      <td className={td}>
                        <StatusBadge status={status} />
                      </td>
                      <td className={`${td} text-xs text-slate-600`}>
                        {live && row.lastCheckedAt ? formatDateTime(row.lastCheckedAt, tz) : dash}
                      </td>
                      <td className={`${td} text-right tabular-nums text-slate-700`}>
                        {live && row.currentHttpStatus !== null ? row.currentHttpStatus : dash}
                      </td>
                      <td className={`${td} text-right tabular-nums ${slow ? "font-medium text-amber-700" : "text-slate-700"}`}>
                        {live && row.currentResponseTimeMs !== null
                          ? formatResponseTime(row.currentResponseTimeMs)
                          : dash}
                      </td>
                      <td className={`${td} text-xs ${slow ? "text-amber-700" : "text-red-700"}`}>
                        {(failing || slow) && row.currentErrorMessage ? (
                          <span className="block max-w-72 truncate" title={row.currentErrorMessage}>
                            {row.currentErrorMessage}
                          </span>
                        ) : (
                          dash
                        )}
                      </td>
                      <td className={`${td} text-xs`}>
                        {failing && row.failureStartedAt ? (
                          <span title={`Not working since ${formatDateTime(row.failureStartedAt, tz)}`}>
                            <span className="font-medium text-red-700">{formatDate(row.failureStartedAt, tz)}</span>
                            <span className="ml-1.5 text-slate-500">({formatElapsed(row.failureStartedAt)})</span>
                          </span>
                        ) : (
                          dash
                        )}
                      </td>
                      {editable && (
                        <td className={`${td} text-right`}>
                          <CheckNowButton id={row.id} name={row.projectName} disabled={!row.monitoringEnabled} />
                        </td>
                      )}
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        )}

        <Pagination
          page={query.page}
          pageCount={pageCount}
          total={total}
          pageSize={DASHBOARD_PAGE_SIZE}
          hrefFor={(page) => dashboardHref(query, { page })}
        />
      </Card>
    </>
  );
}
