"use client";

import * as React from "react";
import { DownloadIcon } from "lucide-react";

import { DiffView, type FieldChange } from "@/components/medora/diff-view";
import { downloadText } from "@/components/medora/file-upload";
import { ListTable } from "@/components/medora/record-lists";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Surface } from "./surface";

/*
 * Activity log (ST-15): who did what, where and when, filterable by user, branch, module and date, and
 * exportable as shown. "View" opens the change as old → new values. Sensitive fields (passwords, keys) say
 * "Changed" and never show values, here or in the export.
 */

export type ActivityEntry = { id: string; at: string; user: string; branch: string; module: string; action: string; record: string; changes: FieldChange[] };

const csvCell = (v: string) => (/[",\n]/.test(v) ? `"${v.replace(/"/g, '""')}"` : v);
const when = (iso: string) => `${iso.slice(8, 10)} ${["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"][Number(iso.slice(5, 7)) - 1]}, ${iso.slice(11, 16)}`;

/**
 * `onRange` (Stage 7, plan C): the page fetches the chosen dates from the server, so the date filter reaches past what is
 * loaded. `canExport` hides the export for a role without Export on the activity log.
 */
export function ActivityLog({ entries, onRange, canExport = true }: { entries: ActivityEntry[]; onRange?: (from: string, to: string) => void; canExport?: boolean }) {
  const [from, setFrom] = React.useState("");
  const [to, setTo] = React.useState("");
  const mounted = React.useRef(false);
  React.useEffect(() => {
    // Only a change of dates asks the page for more; the first render shows what it was given
    if (mounted.current) onRange?.(from, to);
    mounted.current = true;
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [from, to]);
  const dated = entries.filter((e) => (!from || e.at.slice(0, 10) >= from) && (!to || e.at.slice(0, 10) <= to));
  const exportCsv = () => {
    const head = ["When", "User", "Branch", "Module", "Action", "Record", "Changes"];
    const rows = dated.map((e) => [e.at.replace("T", " ").slice(0, 16), e.user, e.branch, e.module, e.action, e.record, e.changes.map((c) => `${c.field}: ${c.sensitive ? "changed" : `${c.before ?? "–"} → ${c.after ?? "–"}`}`).join("; ")].map(csvCell).join(","));
    downloadText("activity-log.csv", [head.join(","), ...rows].join("\n"));
  };
  return (
    <div className="space-y-3">
      <Surface className="flex flex-wrap items-end gap-2">
        <div className="space-y-1">
          <label htmlFor="al-from" className="text-xs font-medium">
            From
          </label>
          <Input id="al-from" type="date" className="w-40" max={to || undefined} value={from} onChange={(e) => setFrom(e.target.value)} />
        </div>
        <div className="space-y-1">
          <label htmlFor="al-to" className="text-xs font-medium">
            To
          </label>
          <Input id="al-to" type="date" className="w-40" min={from || undefined} value={to} onChange={(e) => setTo(e.target.value)} />
        </div>
        {canExport ? (
          <Button size="sm" variant="outline" className="ml-auto" disabled={!dated.length} onClick={exportCsv}>
            <DownloadIcon data-icon="inline-start" />
            Export {dated.length}
          </Button>
        ) : null}
      </Surface>
      <ListTable
        rows={dated}
        rowKey={(e) => e.id}
        search={{ placeholder: "Action or record", text: (e) => `${e.action} ${e.record}` }}
        filters={[
          { label: "User", all: "All users", value: (e) => e.user },
          { label: "Branch", all: "All branches", value: (e) => e.branch },
          { label: "Module", all: "All modules", value: (e) => e.module },
        ]}
        expand={(e) => <DiffView action={e.action} record={e.record} who={e.user} where={e.branch} module={e.module} at={when(e.at)} changes={e.changes} kind={e.action.startsWith("Created") ? "created" : e.action.startsWith("Deactivated") ? "deactivated" : "updated"} />}
        empty="No activity matches these filters."
        cols={[
          { key: "at", header: "When", cell: (e) => <span className="whitespace-nowrap tabular-nums">{when(e.at)}</span> },
          { key: "user", header: "User and branch", cell: (e) => (<>{e.user}<span className="block text-xs text-muted-foreground">{e.branch}</span></>) },
          { key: "module", header: "Module", cell: (e) => e.module },
          { key: "action", header: "Action", cell: (e) => (<>{e.action}<span className="block text-xs text-muted-foreground">{e.record}</span></>) },
          { key: "n", header: "Changes", numeric: true, cell: (e) => e.changes.length },
        ]}
      />
    </div>
  );
}
