import {
  ActionIcon,
  Badge,
  Button,
  Group,
  HoverCard,
  Paper,
  SegmentedControl,
  Stack,
  Table,
  Text,
  Tooltip,
} from "@mantine/core";
import { IconEdit, IconSearch, IconTrash } from "@tabler/icons-react";
import {
  flexRender,
  MRT_GlobalFilterTextInput,
  MRT_TableBodyCellValue,
  MRT_TablePagination,
  MRT_ToolbarAlertBanner,
  useMantineReactTable,
  type MRT_ColumnDef,
  type MRT_RowSelectionState,
} from "mantine-react-table";
import { useCallback, useMemo, useState } from "react";
import { useNavigate } from "react-router";
import { deletePrompt } from "@/lib/features/chatbot/prompt/action";
import PromptTableHeader from "./(widgets)/PromptTableHeader";
import VoiceTab, { type VoiceConfig } from "./(widgets)/VoiceTab";
import type { PromptRow } from "./(widgets)/prompt.types";
import ConfirmModal from "@/layouts/shared/ConfirmModal";

const isVoiceKey = (key: string | null | undefined) =>
  key?.startsWith("voice_") ?? false;

const PromptsClientPage: React.FC<{
  tableProps: { data: PromptRow[]; totalRows: number };
  voiceConfig: VoiceConfig;
}> = ({ tableProps: { data }, voiceConfig }) => {
  const navigate = useNavigate();
  const [activeTab, setActiveTab] = useState<"pipeline" | "agent" | "voice">(
    "pipeline",
  );
  const [rowSelection, setRowSelection] = useState<MRT_RowSelectionState>({});
  const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 });
  const [bulkDeleting, setBulkDeleting] = useState(false);

  const pipelineCount = useMemo(
    () => data.filter((r) => r.prompt_key && !isVoiceKey(r.prompt_key)).length,
    [data],
  );
  const agentCount = useMemo(
    () => data.filter((r) => !r.prompt_key).length,
    [data],
  );

  const filteredData = useMemo(() => {
    if (activeTab === "pipeline")
      return data.filter((r) => r.prompt_key && !isVoiceKey(r.prompt_key));
    if (activeTab === "agent") return data.filter((r) => !r.prompt_key);
    return [];
  }, [data, activeTab]);

  const handleTabChange = (val: string) => {
    setActiveTab(val as "pipeline" | "agent" | "voice");
    setRowSelection({});
    setPagination((p) => ({ ...p, pageIndex: 0 }));
  };

  // ── Confirm modal ─────────────────────────────────────────────────────────
  const [confirmState, setConfirmState] = useState<{
    opened: boolean;
    title: string;
    message: string;
    onConfirm: () => void | Promise<void>;
  }>({ opened: false, title: "", message: "", onConfirm: () => {} });

  const openConfirm = useCallback(
    (opts: {
      title: string;
      message: string;
      onConfirm: () => void | Promise<void>;
    }) => {
      setConfirmState({ opened: true, ...opts });
    },
    [],
  );
  const closeConfirm = useCallback(
    () => setConfirmState((s) => ({ ...s, opened: false })),
    [],
  );

  const onDelete = (row: PromptRow) => {
    openConfirm({
      title: "Delete Prompt",
      message: `Delete prompt "${row.prompt_name}"?\n\nAgents using this prompt may stop working.`,
      onConfirm: async () => {
        await deletePrompt(row.id);
        navigate(0);
      },
    });
  };

  const handleBulkDelete = () => {
    const selected = table.getSelectedRowModel().rows.map((r) => r.original);
    openConfirm({
      title: "Delete Prompts",
      message: `Delete ${selected.length} prompt(s)? This cannot be undone.`,
      onConfirm: async () => {
        setBulkDeleting(true);
        try {
          await Promise.all(selected.map((r) => deletePrompt(r.id)));
          setRowSelection({});
          navigate(0);
        } finally {
          setBulkDeleting(false);
        }
      },
    });
  };

  const columns: MRT_ColumnDef<PromptRow>[] = [
    { accessorKey: "prompt_name", header: "Name", minSize: 200 },
    {
      accessorKey: "prompt_key",
      header: "Pipeline Key",
      minSize: 180,
      Cell: ({ row }) => {
        const key = row.original.prompt_key;
        if (!key)
          return (
            <Text size="xs" c="dimmed">
              —
            </Text>
          );
        return (
          <Badge size="sm" variant="light" color="gray">
            {key}
          </Badge>
        );
      },
    },
    {
      accessorKey: "prompt_value",
      header: "Preview",
      minSize: 320,
      enableSorting: false,
      Cell: ({ row }) => (
        <HoverCard
          width={520}
          shadow="md"
          openDelay={200}
          closeDelay={100}
          withArrow
        >
          <HoverCard.Target>
            <Text size="xs" c="dimmed" lineClamp={2} style={{ maxWidth: 300 }}>
              {row.original.prompt_value}
            </Text>
          </HoverCard.Target>
          <HoverCard.Dropdown>
            <Text
              size="xs"
              style={{
                whiteSpace: "pre-wrap",
                maxHeight: 360,
                overflowY: "auto",
              }}
            >
              {row.original.prompt_value}
            </Text>
          </HoverCard.Dropdown>
        </HoverCard>
      ),
    },
    { accessorKey: "created_by", header: "Created By", minSize: 160 },
    { accessorKey: "updated_by", header: "Updated By", minSize: 160 },
    {
      id: "actions",
      header: "Actions",
      enableSorting: false,
      minSize: 100,
      Cell: ({ row }) => (
        <Group gap={6} wrap="nowrap">
          <Tooltip label="Edit prompt">
            <ActionIcon
              size="sm"
              variant="light"
              color="blue"
              onClick={(e) => {
                e.stopPropagation();
                navigate(`edit/${row.original.id}`);
              }}
            >
              <IconEdit size={14} />
            </ActionIcon>
          </Tooltip>
          <Tooltip label="Delete prompt">
            <ActionIcon
              size="sm"
              variant="light"
              color="red"
              onClick={(e) => {
                e.stopPropagation();
                onDelete(row.original);
              }}
            >
              <IconTrash size={14} />
            </ActionIcon>
          </Tooltip>
        </Group>
      ),
    },
  ];

  const table = useMantineReactTable({
    columns,
    data: filteredData,
    enableSorting: true,
    enableRowSelection: true,
    getRowId: (row) => row.id,
    onRowSelectionChange: setRowSelection,
    state: { rowSelection, pagination },
    onPaginationChange: (updater) => {
      const next =
        typeof updater === "function" ? updater(pagination) : updater;
      setPagination(next);
      window.scrollTo({ top: 0, behavior: "smooth" });
    },
    initialState: { showGlobalFilter: true },
    paginationDisplayMode: "pages",
    mantinePaginationProps: { rowsPerPageOptions: ["10", "25", "50"], p: 0 },
    mantineSelectCheckboxProps: { color: "blue", size: "xs" },
    mantineSelectAllCheckboxProps: { color: "blue", size: "xs" },
    mantineSearchTextInputProps: { size: "sm" },
    enablePinning: false,
  });

  const selectedCount = table.getSelectedRowModel().rows.length;

  return (
    <Stack>
      <ConfirmModal
        opened={confirmState.opened}
        onClose={closeConfirm}
        title={confirmState.title}
        message={confirmState.message}
        confirmLabel="Delete"
        confirmColor="red"
        onConfirm={confirmState.onConfirm}
      />

      <SegmentedControl
        value={activeTab}
        onChange={handleTabChange}
        size="sm"
        data={[
          { value: "pipeline", label: `Pipeline Prompts (${pipelineCount})` },
          { value: "agent", label: `Agent Prompts (${agentCount})` },
          { value: "voice", label: "Voice Prompts" },
        ]}
        w="fit-content"
      />

      <PromptTableHeader
        activeTab={activeTab}
        onCreate={() => navigate("create")}
      />

      {/* ── Voice tab ─────────────────────────────────────────────────────── */}
      {activeTab === "voice" && <VoiceTab voiceConfig={voiceConfig} />}

      {/* ── Pipeline / Agent table ────────────────────────────────────────── */}
      {activeTab !== "voice" && (
        <>
          <MRT_GlobalFilterTextInput
            table={table}
            variant="default"
            size="sm"
            leftSection={<IconSearch size={16} />}
            c="dark.8"
            p={0}
          />

          {selectedCount > 0 && (
            <Group
              p="sm"
              bg="blue.0"
              style={{
                borderRadius: 8,
                border: "1px solid var(--mantine-color-blue-2)",
              }}
              justify="space-between"
            >
              <Text size="sm" fw={500} c="blue.8">
                {selectedCount} prompt{selectedCount > 1 ? "s" : ""} selected
              </Text>
              <Group gap="xs">
                <Button
                  size="xs"
                  variant="light"
                  color="red"
                  leftSection={<IconTrash size={13} />}
                  loading={bulkDeleting}
                  onClick={handleBulkDelete}
                >
                  Delete Selected
                </Button>
                <Button
                  size="xs"
                  variant="subtle"
                  color="gray"
                  onClick={() => setRowSelection({})}
                >
                  Clear
                </Button>
              </Group>
            </Group>
          )}

          <Paper
            bdrs={4}
            style={{
              overflow: "hidden",
              border: "1px solid var(--mantine-color-white-2)",
            }}
          >
            <Table
              fz={11}
              highlightOnHover
              horizontalSpacing="xl"
              verticalSpacing="xs"
              withColumnBorders
              m="0"
            >
              <Table.Thead>
                {table.getHeaderGroups().map((hg) => (
                  <Table.Tr key={hg.id} c="dark.4" bg="gray.1">
                    {hg.headers.map((header) => (
                      <Table.Th key={header.id} px={12}>
                        {header.isPlaceholder
                          ? null
                          : flexRender(
                              header.column.columnDef.Header ??
                                header.column.columnDef.header,
                              header.getContext(),
                            )}
                      </Table.Th>
                    ))}
                  </Table.Tr>
                ))}
              </Table.Thead>
              <Table.Tbody>
                {table.getRowModel().rows.map((row) => (
                  <Table.Tr key={row.id} style={{ cursor: "pointer" }}>
                    {row.getVisibleCells().map((cell) => (
                      <Table.Td
                        key={cell.id}
                        px={12}
                        onClick={() => {
                          if (
                            cell.column.id === "mrt-row-select" ||
                            cell.column.id === "actions"
                          )
                            return;
                          navigate(`edit/${row.original.id}`);
                        }}
                      >
                        <MRT_TableBodyCellValue cell={cell} table={table} />
                      </Table.Td>
                    ))}
                  </Table.Tr>
                ))}
                {filteredData.length === 0 && (
                  <Table.Tr>
                    <Table.Td colSpan={99} ta="center" py="xl" c="dimmed">
                      {activeTab === "pipeline"
                        ? "No pipeline prompts yet. Create one and set a Pipeline Key to control chatbot behaviour from the admin panel."
                        : 'No agent prompts yet. Click "New Prompt" to create one.'}
                    </Table.Td>
                  </Table.Tr>
                )}
              </Table.Tbody>
            </Table>
          </Paper>

          <MRT_TablePagination table={table} />
          <MRT_ToolbarAlertBanner stackAlertBanner table={table} />
        </>
      )}
    </Stack>
  );
};

export default PromptsClientPage;
