"use client";
import { useSearchParams } from "next/navigation";
import { PageHeader, Panel, Metric } from "@/components/shared/page";
import { SelectField, Field } from "@/components/shared/field";
import { Button } from "@/components/ui/button";
import { ChartPanel } from "@/components/shared/chart";
import { useQueryUpdate } from "@/components/shared/tabs";
import { usePreviewRole } from "@/components/layout/preview-context";
import { downloadCsv } from "@/lib/export";
import { currency } from "@/lib/format";
import { isManager } from "@/lib/preview";
import { locations, financials } from "@/features/locations/fixtures";
import { scopedLocations } from "@/features/locations/model";
import { analyticsPoints } from "./fixtures";
import { aggregateAnalytics } from "./model";
const heatDays = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
export function AnalyticsDashboard({
  report,
}: {
  report: "revenue" | "behavior";
}) {
  const role = usePreviewRole(),
    params = useSearchParams(),
    update = useQueryUpdate(),
    manager = isManager(role),
    restricted = manager || role === "investor";
  const allowed = scopedLocations(locations, role),
    requested = params.get("location_id") ?? "";
  const selected = allowed.some((row) => row.id === requested)
    ? requested
    : restricted
      ? (allowed[0]?.id ?? "")
      : "";
  const scope = allowed.filter((row) => !selected || row.id === selected);
  const start = params.get("start_date") ?? "2026-10-01",
    end = params.get("end_date") ?? "2026-10-15",
    period =
      params.get("period") === "weekly"
        ? "weekly"
        : params.get("period") === "monthly"
          ? "monthly"
          : "daily";
  const data = aggregateAnalytics(
    analyticsPoints,
    scope.map((row) => row.id),
    start,
    end,
    period,
  );
  const total = data.reduce(
    (sum, row) => ({
      gross: sum.gross + row.gross,
      cost: sum.cost + row.electrical + row.service,
      sessions: sum.sessions + row.sessions,
      users: sum.users + row.users,
      returning: sum.returning + row.returning,
      duration: sum.duration + row.duration * row.sessions,
    }),
    { gross: 0, cost: 0, sessions: 0, users: 0, returning: 0, duration: 0 },
  );
  const categories = data.map((row) => row.date);
  const title =
    report === "revenue" ? "Revenue Cost Analysis" : "User Behavior Analysis";
  const scopedFinancial = financials.filter(
    (row) =>
      scope.some((location) => location.id === row.locationId) &&
      row.date >= start &&
      row.date <= end,
  );
  const ranked = [...scopedFinancial].sort((a, b) => b.gross - a.gross);
  const dates = analyticsPoints.filter(
    (row) =>
      scope.some((location) => location.id === row.locationId) &&
      row.date >= start &&
      row.date <= end,
  );
  return (
    <div className="space-y-5">
      <PageHeader title={title} />
      <Panel
        title={
          report === "revenue"
            ? "Revenue & Cost Analysis"
            : "User & Behavior Analysis"
        }
        description={
          restricted
            ? "Showing aggregate analytics for your assigned or contracted location."
            : "Compare performance across the charging network."
        }
      >
        <form
          className="grid items-end gap-4 p-5 md:grid-cols-3 xl:grid-cols-6"
          onSubmit={(event) => {
            event.preventDefault();
            const form = new FormData(event.currentTarget);
            update({
              start_date: String(form.get("start_date")),
              end_date: String(form.get("end_date")),
            });
          }}
        >
          <SelectField
            label="Location"
            value={selected}
            disabled={manager}
            options={[
              ...(!restricted ? [{ value: "", label: "All Locations" }] : []),
              ...allowed.map((row) => ({ value: row.id, label: row.name })),
            ]}
            onChange={(event) => update({ location_id: event.target.value })}
          />
          <Field
            label="Start Date"
            name="start_date"
            required
            type="date"
            defaultValue={start}
            max={end}
          />
          <Field
            label="End Date"
            name="end_date"
            required
            type="date"
            defaultValue={end}
            min={start}
          />
          <SelectField
            label="Group By"
            value={period}
            options={[
              { value: "daily", label: "Daily" },
              { value: "weekly", label: "Weekly" },
              { value: "monthly", label: "Monthly" },
            ]}
            onChange={(event) => update({ period: event.target.value })}
          />
          <Button>Apply Filters</Button>
          <Button
            type="button"
            variant="outline"
            onClick={() =>
              downloadCsv(
                title,
                data.map((row) => ({
                  Date: row.date,
                  "Gross Revenue": row.gross,
                  "Electrical Cost": row.electrical,
                  "Service Cost": row.service,
                  Sessions: row.sessions,
                  "Active Users": row.users,
                  "Returning Users": row.returning,
                })),
              )
            }
          >
            Export CSV
          </Button>
        </form>
      </Panel>
      {!data.length ? (
        <Panel title="No analytics available">
          <p className="p-8 text-center text-muted-foreground">
            No fixture activity in the selected date range. Try October 2026.
          </p>
        </Panel>
      ) : report === "revenue" ? (
        <>
          <div className="grid gap-4 sm:grid-cols-3">
            <Metric label="Gross Revenue" value={currency(total.gross)} />
            <Metric label="Total Cost" value={currency(total.cost)} />
            <Metric
              label="Net Revenue"
              value={currency(total.gross - total.cost)}
            />
          </div>
          <ChartPanel
            title="Cost Breakdown"
            type="bar"
            categories={categories}
            series={[
              {
                name: "Electrical Bill",
                data: data.map((row) => row.electrical),
              },
              { name: "Service Fee", data: data.map((row) => row.service) },
            ]}
          />
          <ChartPanel
            title="Financial Growth"
            type="area"
            categories={categories}
            series={[
              { name: "Gross Revenue", data: data.map((row) => row.gross) },
              {
                name: "Net Revenue",
                data: data.map(
                  (row) => row.gross - row.electrical - row.service,
                ),
              },
            ]}
          />
          <div className="grid gap-5 xl:grid-cols-2">
            <ChartPanel
              title="Top Chargepoints by Revenue"
              type="bar"
              categories={ranked.slice(0, 5).map((row) => row.chargepoint)}
              series={[
                {
                  name: "Revenue",
                  data: ranked.slice(0, 5).map((row) => row.gross),
                },
              ]}
            />
            {restricted ? (
              <ChartPanel
                title="Lowest Revenue Chargepoints"
                type="bar"
                categories={ranked
                  .slice(-5)
                  .reverse()
                  .map((row) => row.chargepoint)}
                series={[
                  {
                    name: "Revenue",
                    data: ranked
                      .slice(-5)
                      .reverse()
                      .map((row) => row.gross),
                  },
                ]}
              />
            ) : (
              <ChartPanel
                title="Top Locations by Revenue"
                type="bar"
                categories={scope.map((row) => row.name)}
                series={[
                  {
                    name: "Revenue",
                    data: scope.map((location) =>
                      scopedFinancial
                        .filter((row) => row.locationId === location.id)
                        .reduce((sum, row) => sum + row.gross, 0),
                    ),
                  },
                ]}
              />
            )}
          </div>
        </>
      ) : (
        <>
          <div className="grid gap-4 sm:grid-cols-3">
            <Metric
              label="Session Count"
              value={total.sessions.toLocaleString()}
            />
            <Metric
              label="Returning User Rate"
              value={`${((100 * total.returning) / Math.max(total.users, 1)).toFixed(1)}%`}
            />
            <Metric
              label="Charging Duration Average"
              value={`${(total.duration / Math.max(total.sessions, 1)).toFixed(1)} min`}
            />
          </div>
          <ChartPanel
            title="Active Users"
            type="area"
            categories={categories}
            series={[
              { name: "Active Users", data: data.map((row) => row.users) },
            ]}
          />
          <div className="grid gap-5 xl:grid-cols-3">
            <ChartPanel
              title="Returning Users"
              type="donut"
              categories={["New Users", "Returning Users"]}
              series={[
                {
                  name: "Users",
                  data: [total.users - total.returning, total.returning],
                },
              ]}
            />
            <div className="xl:col-span-2">
              <ChartPanel
                title="Charging Duration Average"
                type="line"
                categories={categories}
                series={[
                  {
                    name: "Minutes",
                    data: data.map((row) => Math.round(row.duration)),
                  },
                ]}
              />
            </div>
          </div>
          {["Session Activity", "Session Start Heatmap"].map(
            (name, heatIndex) => (
              <Panel
                key={name}
                title={name}
                description="Hover a cell to inspect activity by day and hour."
              >
                <div className="overflow-x-auto p-5">
                  <table className="w-full min-w-[650px] border-separate border-spacing-1 text-xs">
                    <thead>
                      <tr>
                        <th className="text-left font-normal text-muted-foreground">
                          Day / Hour
                        </th>
                        {Array.from({ length: 12 }, (_, index) => (
                          <th
                            key={index}
                            className="font-normal text-muted-foreground"
                          >
                            {String(index * 2).padStart(2, "0")}:00
                          </th>
                        ))}
                      </tr>
                    </thead>
                    <tbody>
                      {heatDays.map((day, dayIndex) => (
                        <tr key={day}>
                          <th className="text-left font-normal text-muted-foreground">
                            {day}
                          </th>
                          {Array.from({ length: 12 }, (_, hour) => {
                            const value = dates
                              .filter(
                                (row) =>
                                  (new Date(
                                    row.date + "T00:00:00Z",
                                  ).getUTCDay() +
                                    6) %
                                    7 ===
                                  dayIndex,
                              )
                              .reduce(
                                (sum, row) =>
                                  sum +
                                  (row.hourly[(hour + heatIndex) % 12] ?? 0),
                                0,
                              );
                            return (
                              <td
                                key={hour}
                                tabIndex={0}
                                title={`${day} ${hour * 2}:00 · ${value} sessions`}
                                aria-label={`${day} ${hour * 2}:00: ${value} sessions`}
                                className="h-9 rounded"
                                style={{
                                  backgroundColor: `color-mix(in srgb, var(--primary) ${Math.min(90, 12 + value / 2)}%, transparent)`,
                                }}
                              />
                            );
                          })}
                        </tr>
                      ))}
                    </tbody>
                  </table>
                  <div className="mt-4 flex justify-end gap-2 text-xs text-muted-foreground">
                    <span>Less</span>
                    {[10, 30, 50, 70, 90].map((level) => (
                      <span
                        key={level}
                        className="size-3 rounded-sm"
                        style={{
                          backgroundColor: `color-mix(in srgb, var(--primary) ${level}%, transparent)`,
                        }}
                      />
                    ))}
                    <span>More</span>
                  </div>
                </div>
              </Panel>
            ),
          )}
        </>
      )}
    </div>
  );
}
