import Link from "next/link";
import { CircleCheck, OctagonAlert, Zap, Clock } from "lucide-react";
import { TableToolbar } from "@/components/shared/table-toolbar";
import {
  PaginationControls,
  SortHeading,
} from "@/components/shared/query-controls";
import { EmptyState } from "@/components/shared/panel";
import type { SearchableFilterOption } from "@/components/shared/searchable-filter-field";
import type { Pagination } from "@/lib/list-query";
import { formatEnergyKwh } from "@/lib/format";
import { sessionCost, sessionDate, sessionDuration, sessionStatusLabel, sessionTone } from "./presentation";
import type { Session } from "./types";

const statusToneClasses: Record<ReturnType<typeof sessionTone>, string> = {
  success: "text-success",
  warning: "text-warning",
  danger: "text-destructive",
  info: "text-info",
  neutral: "text-muted-foreground",
};

export function SessionTable({
  data,
  pagination,
  readOnly = false,
  source = "preview",
  paginationEnabled = true,
  loadError,
  loadNotice,
  locationOptions = [],
  chargepointOptions = [],
  scopeLocationId,
  scopeChargepointId,
}: {
  data: Session[];
  pagination?: Pagination;
  readOnly?: boolean;
  source?: "api" | "preview";
  paginationEnabled?: boolean;
  loadError?: string;
  loadNotice?: string;
  locationOptions?: SearchableFilterOption[];
  chargepointOptions?: SearchableFilterOption[];
  scopeLocationId?: string;
  scopeChargepointId?: string;
}) {
  const previewFilters = [
    { name: "status", label: "Status", options: ["Started", "Ended", "Cancelled", "Created"] },
    { name: "locationName", label: "Location" },
    { name: "chargepointName", label: "Chargepoint" },
    { name: "userName", label: "User" },
    { name: "idTag", label: "ID Tag" },
    { name: "from", label: "Start Date", type: "date" as const },
    { name: "to", label: "End Date", type: "date" as const },
  ];
  const apiFilters = [
    {
      name: "location_id",
      label: "Location",
      section: "Scope",
      searchable: true,
      placeholder: "Search location by name or ID...",
      helperText: "Type to narrow locations, choose a match, or paste its ID.",
      options: locationOptions,
    },
    {
      name: "chargepoint_id",
      label: "Chargepoint",
      section: "Scope",
      searchable: true,
      placeholder: "Search chargepoint by name or ID...",
      helperText: "Type to narrow chargepoints, choose a match, or paste its ID.",
      options: chargepointOptions,
    },
    {
      name: "user_id",
      label: "User ID",
      section: "Session details",
      placeholder: "Paste user ID",
    },
    {
      name: "connector_id",
      label: "Connector ID",
      section: "Session details",
      placeholder: "Paste connector ID",
    },
    {
      name: "status",
      label: "Status",
      section: "Session details",
      searchable: true,
      placeholder: "Select or enter backend status",
      options: Array.from(new Set(["active", "stopping", "completed", ...data.map(row => row.status)])),
    },
  ].filter(field => !(scopeLocationId && field.name === "location_id") && !(scopeChargepointId && field.name === "chargepoint_id"));
  return (
    <section className="panel overflow-hidden">
      <TableToolbar
        title="Sessions"
        description="Manage and monitor charging sessions"
        searchKey="query"
        fields={source === "api" ? apiFilters : previewFilters}
        exportIds={data.map((row) => row.id)}
        exportRows={data.map((row) => ({
          Status: row.status,
          Session: row.id,
          Start: row.start,
          End: row.end,
          Location: row.locationName,
          Chargepoint: row.chargepointName,
          User: row.userName,
          Energy: row.energy,
          Cost: row.cost,
        }))}
        showFilters={!readOnly}
        showSearch={source === "preview"}
      />
      {loadError && (
        <p role="alert" className="px-5 pb-3 text-destructive">
          {loadError}
        </p>
      )}
      {loadNotice && (
        <p role="status" className="px-5 pb-3 text-sm text-muted-foreground">
          {loadNotice}
        </p>
      )}
      <div className="overflow-x-auto">
        <table className="data-table min-w-[2400px]">
          <caption className="sr-only">Charging sessions</caption>
          <thead>
            <tr>
              {[
                ["Status", "status"],
                ["Session ID", "id"],
                ["OCPP Transaction ID", "transactionId"],
                ["Start Time", "start"],
                ["End Time", "end"],
                ["Location", "locationName"],
                ["Chargepoint", "chargepointName"],
                ["ID Tag", "idTag"],
                ["User", "userName"],
                ["Duration", "duration"],
                ["Power (kW)", "power"],
                ["Current (A)", "current"],
                ["SOC (%)", "soc"],
                ["Consumption (kWh)", "energy"],
                ["Cost", "cost"],
              ].map(([label, key]) => (
                source === "preview" ? (
                  <SortHeading key={key} label={label} value={key} />
                ) : (
                  <th key={key}>{label}</th>
                )
              ))}
            </tr>
          </thead>
          <tbody>
            {data.map((row) => {
              const Status =
                row.status === "Ended" || row.status === "completed"
                  ? CircleCheck
                  : row.status === "Cancelled" || row.status === "cancelled" || row.status === "failed"
                    ? OctagonAlert
                    : row.status === "Started" || row.status === "active" || row.status === "charging"
                      ? Zap
                      : Clock;
              return (
                <tr key={row.id}>
                  <td>
                    <span className="flex justify-center" title={sessionStatusLabel(row.status)}>
                      <Status
                        aria-label={sessionStatusLabel(row.status)}
                        className={`size-6 ${statusToneClasses[sessionTone(row.status)]}`}
                      />
                    </span>
                  </td>
                  <td className="whitespace-nowrap">
                    <Link
                      className="underline text-muted-foreground"
                      href={`/sessions/${row.id}`}
                    >
                      {row.id}
                    </Link>
                  </td>
                  <td className="whitespace-nowrap">{row.transactionId || "—"}</td>
                  <td className="whitespace-nowrap">{sessionDate(row.start)}</td>

                  <td className="whitespace-nowrap">
                    {row.status === "Started" ? "-" : sessionDate(row.end)}
                  </td>
                  <td>
                    <Link
                      className="underline"
                      href={`/locations/${row.locationId}`}
                    >
                      {row.locationName}
                    </Link>
                  </td>

                  <td>
                    <Link
                      className="underline"
                      href={`/chargepoints/${row.chargepointId}`}
                    >
                      {row.chargepointName}
                    </Link>
                  </td>

                  <td>{row.idTag || "—"}</td>
                  <td className="whitespace-nowrap">
                    {row.userId ? <Link className="underline hover:text-primary" href={`/customers/${encodeURIComponent(row.userId)}`} prefetch={false}>
                      {row.userName === "—" ? "View user" : row.userName}
                    </Link> : row.userName}
                  </td>
                  <td>{sessionDuration(row)}</td>
                  <td>{row.power?.toFixed(2) ?? "—"}</td>
                  <td>{row.current?.toFixed(2) ?? "—"}</td>
                  <td>{row.soc ?? "-"}</td>

                  <td>{formatEnergyKwh(row.energy)}</td>
                  <td className="whitespace-nowrap">{sessionCost(row.cost, row.currency)}</td>
                </tr>
              );
            })}
          </tbody>
        </table>
        {!data.length && <EmptyState title="No sessions found" />}
      </div>
      {pagination && (paginationEnabled || source === "api") && (
        <PaginationControls
          pagination={pagination}
          navigationEnabled={paginationEnabled}
          pageSizeKey={source === "api" ? "limit" : "paginate_limit"}
        />
      )}
    </section>
  );
}
