import { Menu } from "@base-ui/react/menu";
import AddIcon from "@mui/icons-material/Add";
import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
import { Box, Button, List, ListItemButton, ListItemText, Paper, Stack, Tab, Tabs, Typography } from "@mui/material";
import { parseAsStringEnum, useQueryState } from "nuqs";
import { useRef, type SyntheticEvent } from "react";

import Notebooks from "../notebooks/Notebooks";
import { PromptExperimentsView } from "../prompt-experiments/PromptExperimentsView";
import PromptsManagement from "../prompts-management/PromptsManagement";

import { getContentHeight } from "@/constants/layout";
import { TOUR_IDS } from "@/features/task-tour/selectors";
import { dispatchTourEvent, refreshTaskTourTarget, TASK_TOUR_EVENTS } from "@/features/task-tour/tourEvents";

const TAB_TITLES: Record<string, string> = {
  notebooks: "Prompt Notebooks",
  "prompts-management": "Prompts",
  "prompt-experiments": "Prompt Runs",
};

const TAB_SUBTITLES: Record<string, string> = {
  notebooks: "Manage and organize your prompt experiment notebooks",
  "prompts-management": "Manage and organize your prompts",
  "prompt-experiments": "Test and compare different prompt variations and their effectiveness",
};

export const PromptsView = () => {
  const [activeTab, setActiveTab] = useQueryState(
    "tab",
    parseAsStringEnum(["notebooks", "prompts-management", "prompt-experiments"]).withDefault("notebooks")
  );

  // Stable create handler refs — children register their handlers on mount
  const notebooksCreateFn = useRef<() => void>(() => {});
  const promptsCreateFn = useRef<() => void>(() => {});
  const experimentsCreateFn = useRef<() => void>(() => {});
  const experimentsCreateFromExistingFn = useRef<() => void>(() => {});

  // Stable registration callbacks (extracted from refs so identity never changes)
  const registerNotebooksCreate = useRef((fn: () => void) => {
    notebooksCreateFn.current = fn;
  }).current;
  const registerPromptsCreate = useRef((fn: () => void) => {
    promptsCreateFn.current = fn;
  }).current;
  const registerExperimentsCreate = useRef((fn: () => void) => {
    experimentsCreateFn.current = fn;
  }).current;
  const registerExperimentsCreateFromExisting = useRef((fn: () => void) => {
    experimentsCreateFromExistingFn.current = fn;
  }).current;

  const handleTabChange = (_: SyntheticEvent, value: typeof activeTab) => {
    void setActiveTab(value);
    if (value === "prompts-management") {
      dispatchTourEvent(TASK_TOUR_EVENTS.promptsManagementTabOpened);
    }
  };

  return (
    <Stack sx={{ height: getContentHeight() }}>
      <Stack
        direction="row"
        alignItems="center"
        justifyContent="space-between"
        data-tour-id={TOUR_IDS.promptsEntry}
        sx={{
          px: 3,
          pt: 3,
          pb: 2,
          borderBottom: 1,
          borderColor: "divider",
          backgroundColor: "background.paper",
        }}
      >
        <Stack>
          <Typography variant="h5" color="text.primary" fontWeight="bold" mb={0.5}>
            {TAB_TITLES[activeTab]}
          </Typography>
          <Typography variant="body2" color="text.secondary">
            {TAB_SUBTITLES[activeTab]}
          </Typography>
        </Stack>

        {activeTab === "notebooks" && (
          <Button variant="contained" color="primary" startIcon={<AddIcon />} onClick={() => notebooksCreateFn.current()}>
            Notebook
          </Button>
        )}

        {activeTab === "prompts-management" && (
          <Button variant="contained" color="primary" startIcon={<AddIcon />} onClick={() => promptsCreateFn.current()}>
            Prompt
          </Button>
        )}

        {activeTab === "prompt-experiments" && (
          // Base UI menu (vs MUI's Menu) positions the popup at its final rect
          // immediately instead of growing into place via a transform animation,
          // so the task-tour spotlight/popover anchored to "Create New" resolves
          // against a stable rect rather than the mid-animation one.
          <Menu.Root
            onOpenChange={(open) => {
              if (open) window.requestAnimationFrame(() => refreshTaskTourTarget());
            }}
          >
            <Menu.Trigger
              render={
                <Button
                  variant="contained"
                  color="primary"
                  startIcon={<AddIcon />}
                  endIcon={<ArrowDropDownIcon />}
                  data-tour-id={TOUR_IDS.promptsExperimentButton}
                />
              }
            >
              Experiment
            </Menu.Trigger>
            <Menu.Portal>
              <Menu.Positioner side="bottom" align="end" sideOffset={4}>
                <Menu.Popup render={<List component={Paper} dense className="outline-none min-w-(--anchor-width)" />}>
                  <Menu.Item
                    render={
                      <ListItemButton
                        data-tour-id={TOUR_IDS.promptsExperimentCreateNew}
                        onClick={() => {
                          dispatchTourEvent(TASK_TOUR_EVENTS.createExperimentModalOpened);
                          experimentsCreateFn.current();
                        }}
                      />
                    }
                  >
                    <ListItemText primary="Create New" />
                  </Menu.Item>
                  <Menu.Item render={<ListItemButton onClick={() => experimentsCreateFromExistingFn.current()} />}>
                    <ListItemText primary="Create from Existing" />
                  </Menu.Item>
                </Menu.Popup>
              </Menu.Positioner>
            </Menu.Portal>
          </Menu.Root>
        )}
      </Stack>

      <Tabs
        variant="fullWidth"
        value={activeTab}
        onChange={handleTabChange}
        sx={{ backgroundColor: "background.paper", borderBottom: 1, borderColor: "divider" }}
      >
        <Tab label="Notebooks" value="notebooks" />
        <Tab label="Prompts" value="prompts-management" data-tour-id={TOUR_IDS.promptsManagementTab} />
        <Tab label="Runs" value="prompt-experiments" />
      </Tabs>

      <Box sx={{ flex: 1, overflow: "auto", display: "flex", flexDirection: "column" }}>
        {activeTab === "notebooks" && <Notebooks onRegisterCreate={registerNotebooksCreate} />}
        {activeTab === "prompts-management" && <PromptsManagement onRegisterCreate={registerPromptsCreate} />}
        {activeTab === "prompt-experiments" && (
          <PromptExperimentsView onRegisterCreate={registerExperimentsCreate} onRegisterCreateFromExisting={registerExperimentsCreateFromExisting} />
        )}
      </Box>
    </Stack>
  );
};
