"use client";

/**
 * Import history, with a console-only delete.
 *
 * WHAT DELETE DOES, AND WHAT IT DOES NOT
 *
 * It removes rows from console2's own tables. Viewpoint is never contacted and is
 * never modified — it remains the system of record, so anything removed here still
 * exists there and comes back if the same report is imported again. That makes this
 * an undo for a mistaken or badly mapped import, not a way to cancel a booking, and
 * the wording throughout says so rather than leaving it to be assumed.
 *
 * The upload record survives a delete on purpose: it records who uploaded which
 * file, when, and how it was mapped, which is the audit trail for the data being
 * removed. A row showing "0 stored" is an upload whose data has been deleted, which
 * is more useful than the upload having silently vanished.
 */

import {
  Alert,
  Badge,
  Button,
  Group,
  Modal,
  Skeleton,
  Stack,
  Table,
  Text,
  Tooltip,
} from "@mantine/core";
import { notifications } from "@mantine/notifications";
import { IconAlertTriangle, IconTrash } from "@tabler/icons-react";
import { useCallback, useEffect, useState } from "react";
import {
  deleteViewpointData,
  listViewpointImports,
  type ViewpointImportRow,
  type ViewpointReportType,
} from "@/lib/features/viewpoint/query";
import styles from "@/routes/promo-code-campaigns/_components/promo.module.css";

function formatWhen(value: string | null): string {
  if (!value) return "—";
  const d = new Date(value);
  return Number.isFinite(d.getTime()) ? d.toLocaleString() : "—";
}

const REPORT_LABEL: Record<ViewpointReportType, string> = {
  bookings: "Bookings by source",
  member_contacts: "Member contacts",
};

/** What a pending confirmation is about. */
type Pending =
  | { kind: "import"; row: ViewpointImportRow }
  | { kind: "all"; reportType: ViewpointReportType };

export function ViewpointImportHistory({
  opened,
  onClose,
  canDelete,
  reportType,
  onChanged,
}: {
  opened: boolean;
  onClose: () => void;
  /** Super admin. Deleting changes what every user sees. */
  canDelete: boolean;
  /** The report currently on screen, for the delete-everything action. */
  reportType: ViewpointReportType;
  /** Fired after a delete so the dashboard refetches. */
  onChanged: () => void;
}) {
  const [items, setItems] = useState<ViewpointImportRow[]>([]);
  const [loading, setLoading] = useState(true);
  const [pending, setPending] = useState<Pending | null>(null);
  const [busy, setBusy] = useState(false);

  const load = useCallback(async () => {
    setLoading(true);
    const res = await listViewpointImports();
    setItems(res.success && res.data ? res.data.items : []);
    setLoading(false);
  }, []);

  useEffect(() => {
    if (opened) void load();
  }, [opened, load]);

  const runDelete = async () => {
    if (!pending) return;
    setBusy(true);
    const res =
      pending.kind === "import"
        ? await deleteViewpointData({
          reportType: pending.row.report_type,
          importId: pending.row.id,
        })
        : await deleteViewpointData({
          reportType: pending.reportType,
          confirmAll: true,
        });
    setBusy(false);
    setPending(null);

    if (!res.success || !res.data) {
      notifications.show({
        color: "red",
        title: "Nothing was deleted",
        message: res.message || "Could not remove the imported rows.",
      });
      return;
    }
    notifications.show({
      color: "green",
      title: "Removed from console2",
      // Restates the boundary at the moment it matters most.
      message: `${res.data.deleted} row${res.data.deleted === 1 ? "" : "s"} deleted. Viewpoint is unchanged — re-importing the report restores them.`,
      autoClose: 8000,
    });
    await load();
    onChanged();
  };

  return (
    <>
      <Modal
        opened={opened}
        onClose={onClose}
        title="Viewpoint imports"
        size="xl"
        centered
      >
        <Stack gap="sm">
          <Alert color="blue" variant="light">
            Deleting removes rows from <strong>console2 only</strong>. Viewpoint is
            never modified, so anything deleted here still exists there and returns
            if the same report is imported again. The upload record is kept as the
            audit trail.
          </Alert>

          {loading ? (
            <Stack gap={6}>
              {Array.from({ length: 4 }, (_, i) => (
                <Skeleton key={i} height={36} radius="sm" />
              ))}
            </Stack>
          ) : items.length === 0 ? (
            <Text size="sm" c="dimmed" py="xl" ta="center">
              Nothing has been imported yet.
            </Text>
          ) : (
            <Table stickyHeader style={{ minWidth: 860 }}>
              <Table.Thead className={styles.tableHead}>
                <Table.Tr>
                  <Table.Th className={styles.th}>File</Table.Th>
                  <Table.Th className={styles.th}>Report</Table.Th>
                  <Table.Th className={styles.th}>Uploaded</Table.Th>
                  <Table.Th className={styles.th}>By</Table.Th>
                  <Table.Th className={styles.th}>Rows in file</Table.Th>
                  <Table.Th className={styles.th}>Added / updated</Table.Th>
                  <Table.Th className={styles.th}>Stored now</Table.Th>
                  {canDelete && <Table.Th className={styles.th} />}
                </Table.Tr>
              </Table.Thead>
              <Table.Tbody>
                {items.map((r) => (
                  <Table.Tr key={r.id} className={styles.row}>
                    <Table.Td>
                      <Stack gap={0}>
                        <Text size="sm" lineClamp={1}>
                          {r.filename}
                        </Text>
                        {r.sheet_name && (
                          <Text size="xs" c="dimmed">
                            {r.sheet_name}
                          </Text>
                        )}
                      </Stack>
                    </Table.Td>
                    {/* <Table.Td>
                      <Badge variant="light" size="sm">
                        {REPORT_LABEL[r.report_type]}
                      </Badge>
                    </Table.Td> */}
                    <Table.Td className={styles.num}>
                      {formatWhen(r.created_at)}
                    </Table.Td>
                    <Table.Td>
                      <Text size="xs">{r.uploaded_by ?? "—"}</Text>
                    </Table.Td>
                    <Table.Td className={styles.num}>{r.row_count}</Table.Td>
                    <Table.Td className={styles.num}>
                      {r.inserted_count} / {r.updated_count}
                      {r.skipped_count > 0 && (
                        <Tooltip
                          label={`${r.skipped_count} rows had no identifying number and were not stored`}
                        >
                          <Text span size="xs" c="orange">
                            {" "}
                            · {r.skipped_count} skipped
                          </Text>
                        </Tooltip>
                      )}
                    </Table.Td>
                    <Table.Td className={styles.num}>
                      {/*
                        The live count, which is what a delete would remove — not
                        `inserted_count`. A later import of the same bookings takes
                        those rows over, so an older batch's figure falls to 0 without
                        anything having been deleted.
                      */}
                      {r.storedRows === 0 ? (
                        <Text size="xs" c="dimmed">
                          0
                        </Text>
                      ) : (
                        r.storedRows
                      )}
                    </Table.Td>
                    {canDelete && (
                      <Table.Td>
                        <Button
                          size="compact-xs"
                          variant="light"
                          color="red"
                          leftSection={<IconTrash size={13} />}
                          disabled={r.storedRows === 0}
                          onClick={() => setPending({ kind: "import", row: r })}
                        >
                          Delete rows
                        </Button>
                      </Table.Td>
                    )}
                  </Table.Tr>
                ))}
              </Table.Tbody>
            </Table>
          )}

          {canDelete && items.length > 0 && (
            <Group justify="flex-end">
              <Button
                size="xs"
                variant="light"
                color="red"
                leftSection={<IconTrash size={14} />}
                onClick={() => setPending({ kind: "all", reportType })}
              >
                Delete all {REPORT_LABEL[reportType].toLowerCase()} rows
              </Button>
            </Group>
          )}
        </Stack>
      </Modal>

      {/*
        A separate confirmation rather than a window.confirm: the count and the
        Viewpoint boundary both need stating, and neither fits in a browser dialog.
      */}
      <Modal
        opened={pending !== null}
        onClose={() => setPending(null)}
        title="Delete imported rows?"
        centered
      >
        <Stack gap="sm">
          <Alert
            color="orange"
            variant="light"
            icon={<IconAlertTriangle size={16} />}
          >
            {pending?.kind === "import"
              ? `This removes the ${pending.row.storedRows} row${pending.row.storedRows === 1 ? "" : "s"} currently stored from "${pending.row.filename}".`
              : `This removes every stored ${pending ? REPORT_LABEL[pending.reportType].toLowerCase() : ""} row.`}
          </Alert>
          <Text size="sm">
            Only console2 is affected. Viewpoint keeps its data, and importing the
            report again restores these rows.
          </Text>
          <Group justify="flex-end">
            <Button variant="default" onClick={() => setPending(null)}>
              Cancel
            </Button>
            <Button color="red" loading={busy} onClick={() => void runDelete()}>
              Delete
            </Button>
          </Group>
        </Stack>
      </Modal>
    </>
  );
}
