"use client";

import {
  Badge,
  Button,
  Drawer,
  Flex,
  Group,
  Modal,
  Pagination,
  SegmentedControl,
  Select,
  Stack,
  Table,
  Text,
  TextInput,
  Title,
} from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { notifications } from "@mantine/notifications";
import {
  IconCode,
  IconFileZip,
  IconFolderPlus,
  IconHistory,
  IconMail,
  IconPlus,
  IconRefresh,
  IconSearch,
  IconTrash,
} from "@tabler/icons-react";
import moment from "moment";
import React, { useMemo, useState } from "react";
import { useNavigate } from "react-router";
import { createEDMFolder, deleteEDMTemplate } from "@/lib/features/edm/action";
import { listEDMFolders, listEDMTemplates } from "@/lib/features/edm/query";
import type { EDMFolder, EDMTemplate } from "@/lib/features/edm/types";
import type { AccessScope } from "@/lib/features/types";
import { useRoleAccess } from "@/hooks/useRoleAccess";
import { folderSelectOptions } from "@/lib/features/edm/folderTree";
import { EDMLogsPanel } from "./_components/EDMLogsPanel";
import { EDMFolderBrowser } from "./_components/EDMFolderBrowser";
import { EDMStorageTargetControl } from "./_components/EDMStorageTargetControl";

interface Props {
  initialTemplates: EDMTemplate[];
  initialFolders: EDMFolder[];
  initialError?: string;
  accessScope: AccessScope;
}

const PAGE_SIZE_OPTIONS = ["10", "20", "50"];

export default function EDMListClientPage({
  initialTemplates,
  initialFolders,
  initialError,
  accessScope,
}: Props) {
  const navigate = useNavigate();
  const { checkClientAccess } = useRoleAccess();
  const canViewAdminLogs = checkClientAccess("read", "admin-logs");
  const [templates, setTemplates] = useState<EDMTemplate[]>(initialTemplates);
  const [loading, setLoading] = useState(false);
  const [search, setSearch] = useState("");
  const [statusFilter, setStatusFilter] = useState<string | null>(null);
  const [pageSize, setPageSize] = useState("10");
  const [page, setPage] = useState(1);

  const [deleteTarget, setDeleteTarget] = useState<EDMTemplate | null>(null);
  const [deleting, setDeleting] = useState(false);
  const [deleteOpened, { open: openDelete, close: closeDelete }] =
    useDisclosure(false);
  const [historyOpened, { open: openHistory, close: closeHistory }] =
    useDisclosure(false);

  const [folders, setFolders] = useState<EDMFolder[]>(initialFolders);
  // Folders first on entry; the lists are for finding a template by name, and
  // the store split shows what is still left in SendGrid during the migration.
  const [view, setView] = useState<"browse" | "all" | "gcs" | "sendgrid">(
    "browse",
  );
  // Bumped to make the browser refetch after a folder is created here.
  const [browseToken, setBrowseToken] = useState(0);
  const [newFolderOpened, { open: openNewFolder, close: closeNewFolder }] =
    useDisclosure(false);
  const [newFolderName, setNewFolderName] = useState("");
  const [newFolderParent, setNewFolderParent] = useState<string | null>(null);
  const [creatingFolder, setCreatingFolder] = useState(false);

  const folderOptions = useMemo(() => folderSelectOptions(folders), [folders]);

  const handleCreateFolder = async () => {
    if (!newFolderName.trim()) return;
    setCreatingFolder(true);
    try {
      const res = await createEDMFolder({
        name: newFolderName.trim(),
        parent_id: newFolderParent,
      });
      if (res.success && res.data) {
        setFolders((prev) => [...prev, res.data]);
        setNewFolderName("");
        setNewFolderParent(null);
        closeNewFolder();
        setBrowseToken((n) => n + 1);
        notifications.show({ color: "green", message: "Folder created" });
      } else {
        notifications.show({
          color: "red",
          message: res.message || "Failed to create folder",
        });
      }
    } finally {
      setCreatingFolder(false);
    }
  };

  const refreshFolders = async () => {
    const res = await listEDMFolders();
    if (res.success && Array.isArray(res.data)) setFolders(res.data);
  };

  const refresh = async () => {
    setLoading(true);
    try {
      const res = await listEDMTemplates();
      if (res.success && Array.isArray(res.data)) {
        setTemplates(res.data);
        setPage(1);
      } else {
        notifications.show({
          color: "red",
          message: res.message || "Failed to refresh",
        });
      }
    } catch {
      notifications.show({
        color: "red",
        message: "Failed to refresh templates",
      });
    } finally {
      setLoading(false);
    }
  };

  const activeVersion = (t: EDMTemplate) =>
    t.versions.find((v) => v.active === 1) ?? t.versions[0] ?? null;

  const filtered = useMemo(() => {
    const q = search.trim().toLowerCase();
    return templates.filter((t) => {
      const ver = activeVersion(t);
      if (
        q &&
        !t.name.toLowerCase().includes(q) &&
        !t.id.toLowerCase().includes(q) &&
        !(ver?.subject ?? "").toLowerCase().includes(q)
      )
        return false;
      if (statusFilter === "active" && ver?.active !== 1) return false;
      if (statusFilter === "inactive" && ver?.active === 1) return false;
      if (statusFilter === "no-version" && t.versions.length > 0) return false;
      // Anything not explicitly SendGrid's is in the local (GCS) store. The
      // SendGrid view also keeps migrated templates, whose SendGrid copy remains.
      if (view === "sendgrid" && t.store !== "sendgrid" && !t.inSendGrid)
        return false;
      if (view === "gcs" && t.store === "sendgrid") return false;
      return true;
    });
  }, [templates, search, statusFilter, view]);

  const totalPages = Math.ceil(filtered.length / parseInt(pageSize, 10));
  const paginated = filtered.slice(
    (page - 1) * parseInt(pageSize, 10),
    page * parseInt(pageSize, 10),
  );

  const handleDeleteClick = (e: React.MouseEvent, template: EDMTemplate) => {
    e.stopPropagation();
    setDeleteTarget(template);
    openDelete();
  };

  const handleDeleteConfirm = async () => {
    if (!deleteTarget) return;
    setDeleting(true);
    try {
      const res = await deleteEDMTemplate(deleteTarget.id);
      if (res.success) {
        notifications.show({ color: "green", message: "Template deleted" });
        setTemplates((prev) => prev.filter((t) => t.id !== deleteTarget.id));
        closeDelete();
      } else {
        notifications.show({
          color: "red",
          message: res.message || "Delete failed",
        });
      }
    } catch {
      notifications.show({ color: "red", message: "Delete failed" });
    } finally {
      setDeleting(false);
    }
  };

  return (
    <Stack px={28} py={20} gap="lg">
      {/* Header */}
      <Flex justify="space-between" align="center">
        <Group gap="sm">
          <IconMail size={24} />
          <Title order={3}>Email Templates</Title>
          <EDMStorageTargetControl />
        </Group>
        <Group>
          {canViewAdminLogs && (
            <Button
              variant="light"
              color="gray"
              leftSection={<IconHistory size={16} />}
              onClick={openHistory}
            >
              Activity
            </Button>
          )}
          <Button
            variant="light"
            leftSection={<IconRefresh size={16} />}
            onClick={refresh}
            loading={loading}
          >
            Refresh
          </Button>
          <Button
            variant="light"
            color="indigo"
            leftSection={<IconCode size={16} />}
            onClick={() => navigate("/admin/edm/workspace")}
          >
            Workspace
          </Button>
          {accessScope.create && (
            <Button
              variant="light"
              color="grape"
              leftSection={<IconFileZip size={16} />}
              onClick={() => navigate("/admin/edm/import")}
            >
              Import
            </Button>
          )}
          {accessScope.create && (
            <Button
              leftSection={<IconPlus size={16} />}
              onClick={() => navigate("/admin/edm/new")}
            >
              New Template
            </Button>
          )}
        </Group>
      </Flex>

      {initialError && (
        <Text size="sm" c="red">
          {initialError}
        </Text>
      )}

      {/* Browse is the primary view; the flat table stays for finding a
          template by name across every folder at once. */}
      <SegmentedControl
        value={view}
        onChange={(v) => {
          setView(v as "browse" | "all" | "gcs" | "sendgrid");
          setPage(1);
          // Refetch rather than filter what the page loaded with: a template
          // migrated since then would still be listed under its old store.
          if (v !== "browse") void refresh();
        }}
        maw={560}
        data={[
          { value: "browse", label: "Browse folders" },
          { value: "gcs", label: "GCS templates" },
          { value: "sendgrid", label: "SendGrid templates" },
          { value: "all", label: "All templates" },
        ]}
      />

      {view === "browse" && (
        <EDMFolderBrowser
          accessScope={accessScope}
          refreshToken={browseToken}
        />
      )}

      {view !== "browse" && (
        <>
          {/* Filter bar */}
          <Group
            justify="space-between"
            align="center"
            style={{
              backgroundColor: "var(--mantine-color-gray-0)",
              padding: "16px",
              borderRadius: "12px",
            }}
          >
            <TextInput
              placeholder="Search by name, ID or subject…"
              leftSection={<IconSearch size={16} stroke={1.5} />}
              value={search}
              onChange={(e) => {
                setSearch(e.currentTarget.value);
                setPage(1);
              }}
              size="sm"
              radius="md"
              variant="filled"
              style={{ flex: 1, maxWidth: 400 }}
            />
            <Group gap="xs">
              {accessScope.create && (
                <Button
                  variant="subtle"
                  size="sm"
                  leftSection={<IconFolderPlus size={16} />}
                  onClick={openNewFolder}
                >
                  Folder
                </Button>
              )}
              <Select
                placeholder="Status"
                data={[
                  { value: "active", label: "Active" },
                  { value: "inactive", label: "Inactive" },
                  { value: "no-version", label: "No version" },
                ]}
                value={statusFilter}
                onChange={(val) => {
                  setStatusFilter(val);
                  setPage(1);
                }}
                clearable
                size="sm"
                radius="md"
                variant="filled"
                style={{ width: 140 }}
              />
            </Group>
          </Group>

          <Stack gap="md">
            {filtered.length === 0 ? (
              <Stack align="center" py="xl" gap="xs">
                <IconMail size={40} opacity={0.3} />
                <Text c="dimmed" size="md">
                  {search || statusFilter
                    ? "No templates match your filters."
                    : "No email templates found."}
                </Text>
                {accessScope.create && !search && !statusFilter && (
                  <Button
                    variant="subtle"
                    leftSection={<IconPlus size={14} />}
                    onClick={() => navigate("/admin/edm/new")}
                  >
                    Create your first template
                  </Button>
                )}
              </Stack>
            ) : (
              <>
                <Table striped highlightOnHover withTableBorder>
                  <Table.Thead>
                    <Table.Tr>
                      <Table.Th>Name</Table.Th>
                      <Table.Th>Template ID</Table.Th>
                      <Table.Th>Subject</Table.Th>
                      <Table.Th>Status</Table.Th>
                      <Table.Th>Stored in</Table.Th>
                      <Table.Th>Updated</Table.Th>
                      {accessScope.delete && <Table.Th style={{ width: 60 }} />}
                    </Table.Tr>
                  </Table.Thead>
                  <Table.Tbody>
                    {paginated.map((t) => {
                      const ver = activeVersion(t);
                      return (
                        <Table.Tr
                          key={t.id}
                          style={{ cursor: "pointer" }}
                          onClick={() => navigate(`/admin/edm/${t.id}`)}
                        >
                          <Table.Td>
                            <Text fw={600} size="sm">
                              {t.name}
                            </Text>
                          </Table.Td>
                          <Table.Td>
                            <Text size="sm" c="dimmed" ff="monospace">
                              {t.id}
                            </Text>
                          </Table.Td>
                          <Table.Td>
                            <Text size="sm">
                              {ver?.subject || (
                                <Text span c="dimmed">
                                  —
                                </Text>
                              )}
                            </Text>
                          </Table.Td>
                          <Table.Td>
                            {ver ? (
                              <Badge
                                color={ver.active === 1 ? "green" : "gray"}
                                variant="light"
                                size="sm"
                              >
                                {ver.active === 1 ? "Active" : "Inactive"}
                              </Badge>
                            ) : (
                              <Badge color="orange" variant="light" size="sm">
                                No version
                              </Badge>
                            )}
                          </Table.Td>
                          <Table.Td>
                            {/*
                          Where this one lives, which is what decides where an
                          edit or a delete goes — not the console-wide setting,
                          which only applies to templates created from now on.
                        */}
                            <Badge
                              size="sm"
                              variant="light"
                              color={t.store === "sendgrid" ? "grape" : "teal"}
                            >
                              {t.store === "sendgrid" ? "SendGrid" : "GCS"}
                            </Badge>
                            {t.store !== "sendgrid" && t.inSendGrid && (
                              <Badge size="sm" variant="outline" color="grape" ml={4}>
                                Migrated
                              </Badge>
                            )}
                          </Table.Td>
                          <Table.Td>
                            <Text size="sm" c="dimmed">
                              {t.updated_at
                                ? moment(t.updated_at).format(
                                  "DD MMM YYYY, HH:mm",
                                )
                                : "—"}
                            </Text>
                          </Table.Td>
                          {accessScope.delete && (
                            <Table.Td>
                              <Button
                                size="compact-sm"
                                variant="subtle"
                                color="red"
                                leftSection={<IconTrash size={14} />}
                                onClick={(e) => handleDeleteClick(e, t)}
                              >
                                Delete
                              </Button>
                            </Table.Td>
                          )}
                        </Table.Tr>
                      );
                    })}
                  </Table.Tbody>
                </Table>

                <Flex justify="space-between" align="center">
                  <Group gap="xs">
                    <Select
                      style={{ width: 80 }}
                      data={PAGE_SIZE_OPTIONS}
                      value={pageSize}
                      onChange={(val) => {
                        setPageSize(val ?? "10");
                        setPage(1);
                      }}
                      size="sm"
                    />
                    <Text size="sm" c="dimmed">
                      Entries per page
                    </Text>
                  </Group>
                  <Group gap="xs">
                    <Text size="sm" c="dimmed">
                      {filtered.length} template
                      {filtered.length !== 1 ? "s" : ""}
                    </Text>
                    <Pagination
                      total={totalPages}
                      value={page}
                      onChange={setPage}
                      size="sm"
                    />
                  </Group>
                </Flex>
              </>
            )}
          </Stack>
        </>
      )}
      {/* Delete confirmation */}
      <Modal
        opened={deleteOpened}
        onClose={closeDelete}
        title="Delete Email Template"
        centered
        size="sm"
      >
        <Stack>
          <Text size="sm">
            Are you sure you want to delete{" "}
            <Text span fw={700}>
              {deleteTarget?.name}
            </Text>
            ? This will permanently delete the template and all its versions
            from SendGrid.
          </Text>
          <Text size="xs" c="dimmed" ff="monospace">
            {deleteTarget?.id}
          </Text>
          <Group justify="flex-end">
            <Button variant="subtle" onClick={closeDelete}>
              Cancel
            </Button>
            <Button
              color="red"
              onClick={handleDeleteConfirm}
              loading={deleting}
            >
              Delete
            </Button>
          </Group>
        </Stack>
      </Modal>

      {/* New folder */}
      <Modal
        opened={newFolderOpened}
        onClose={closeNewFolder}
        title="New folder"
        centered
        size="sm"
      >
        <Stack>
          <TextInput
            label="Folder name"
            placeholder="e.g. Campaigns 2026"
            value={newFolderName}
            onChange={(e) => setNewFolderName(e.currentTarget.value)}
            onKeyDown={(e) => {
              if (e.key === "Enter") void handleCreateFolder();
            }}
            data-autofocus
          />
          <Select
            label="Inside"
            placeholder="Top level"
            data={folderOptions}
            value={newFolderParent}
            onChange={setNewFolderParent}
            clearable
            searchable
          />
          <Group justify="flex-end">
            <Button variant="subtle" onClick={closeNewFolder}>
              Cancel
            </Button>
            <Button onClick={handleCreateFolder} loading={creatingFolder}>
              Create
            </Button>
          </Group>
        </Stack>
      </Modal>

      {/* General activity drawer */}
      {canViewAdminLogs && (
        <Drawer
          opened={historyOpened}
          onClose={closeHistory}
          title="Email Template Activity"
          position="right"
          size="md"
        >
          <EDMLogsPanel templateId={null} />
        </Drawer>
      )}
    </Stack>
  );
}
