import { TextOperators, TracesEmptyState } from "@arthur/shared-components";
import { Search } from "@mui/icons-material";
import {
  Box,
  Button,
  Dialog,
  Paper,
  Stack,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TablePagination,
  TableRow,
  TextField,
} from "@mui/material";
import { useSuspenseQuery } from "@tanstack/react-query";
import { flexRender, getCoreRowModel, useReactTable } from "@tanstack/react-table";
import { parseAsString, parseAsStringEnum, useQueryState } from "nuqs";
import { useEffect, useMemo, useState } from "react";

import { createColumns } from "../../data/results-columns";
import { continuousEvalsResultsQueryOptions } from "../../hooks/useContinuousEvalsResults";

import { Details } from "./components/details";
import { FilterModal } from "./components/FilterModal";

import { useFilterStore } from "@/components/traces/stores/filter.store";
import { useDisplaySettings } from "@/contexts/DisplaySettingsContext";
import { TOUR_IDS, tourDataAttr } from "@/features/task-tour/selectors";
import { dispatchTourEvent, refreshTaskTourTarget, TASK_TOUR_EVENTS } from "@/features/task-tour/tourEvents";
import { useApi } from "@/hooks/useApi";
import { usePagination } from "@/hooks/usePagination";
import { useTask } from "@/hooks/useTask";

export const Results = () => {
  const api = useApi()!;
  const { task } = useTask();
  const { defaultCurrency } = useDisplaySettings();

  const [annotationId, setAnnotationId] = useQueryState("id", parseAsString.withDefault(""));
  const [action, setAction] = useQueryState("action", parseAsStringEnum(["rerun"]));

  const [searchInput, setSearchInput] = useState("");
  const filters = useFilterStore((state) => state.filters);
  const setFilters = useFilterStore((state) => state.setFilters);
  const pagination = usePagination();

  const handleSearch = () => {
    if (searchInput.trim()) {
      const existingFilters = filters.filter((f) => f.name !== "eval_name");
      setFilters([
        ...existingFilters,
        {
          name: "eval_name",
          operator: TextOperators.CONTAINS,
          value: searchInput.trim(),
        },
      ]);
    } else {
      // Clear the eval_name filter if search is empty
      setFilters(filters.filter((f) => f.name !== "eval_name"));
    }
  };

  const { data } = useSuspenseQuery(
    continuousEvalsResultsQueryOptions({
      api,
      taskId: task!.id,
      pagination: { page: pagination.page, page_size: pagination.rowsPerPage },
      filters,
    })
  );

  const table = useReactTable({
    data: data.annotations,
    columns: useMemo(
      () => createColumns({ onView: (annotationId) => setAnnotationId(annotationId), defaultCurrency }),
      [setAnnotationId, defaultCurrency]
    ),
    getCoreRowModel: getCoreRowModel(),
  });

  useEffect(() => {
    if (!annotationId) return;
    const frame = window.requestAnimationFrame(() => refreshTaskTourTarget());
    return () => window.cancelAnimationFrame(frame);
  }, [annotationId]);

  const handleCloseDetails = () => {
    setAnnotationId("");
    dispatchTourEvent(TASK_TOUR_EVENTS.evaluateResultDetailsReviewed);
  };

  return (
    <>
      <Stack
        direction="row"
        spacing={2}
        alignItems="center"
        sx={{ p: 2, borderBottom: "1px solid", borderColor: "divider", backgroundColor: "background.paper" }}
      >
        <TextField
          size="small"
          placeholder="Search by eval name"
          value={searchInput}
          onChange={(e) => setSearchInput(e.target.value)}
          onKeyDown={(e) => {
            if (e.key === "Enter") {
              handleSearch();
            }
          }}
          sx={{ width: 300 }}
        />
        <Button variant="outlined" startIcon={<Search />} onClick={handleSearch}>
          Search
        </Button>
        <FilterModal />
      </Stack>
      {data.annotations.length === 0 ? (
        <Box sx={{ p: 2 }}>
          <TracesEmptyState title="No annotations found" />
        </Box>
      ) : (
        <>
          <TableContainer component={Paper} elevation={0} sx={{ flexGrow: 0, flexShrink: 1 }}>
            <Table stickyHeader>
              <TableHead>
                {table.getHeaderGroups().map((header) => (
                  <TableRow key={header.id}>
                    {header.headers.map((header) => (
                      <TableCell
                        key={header.id}
                        sx={{
                          fontWeight: 600,
                        }}
                      >
                        {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}
                      </TableCell>
                    ))}
                  </TableRow>
                ))}
              </TableHead>
              <TableBody>
                {table.getRowModel().rows.map((row) => (
                  <TableRow
                    key={row.id}
                    hover
                    onClick={() => setAnnotationId(row.original.id)}
                    data-tour-id={row.index === 0 ? TOUR_IDS.evaluateResultsFirstRow : undefined}
                    sx={{ cursor: "pointer" }}
                  >
                    {row.getVisibleCells().map((cell) => (
                      <TableCell key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</TableCell>
                    ))}
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </TableContainer>
          <TablePagination
            component="div"
            count={data.count}
            page={pagination.page}
            onPageChange={pagination.handlePageChange}
            rowsPerPage={pagination.rowsPerPage}
            onRowsPerPageChange={pagination.handleRowsPerPageChange}
            sx={{
              overflow: "visible",
            }}
          />
        </>
      )}

      <Dialog
        open={!!annotationId}
        onClose={handleCloseDetails}
        maxWidth="xl"
        fullWidth
        slotProps={{
          paper: {
            ...tourDataAttr(TOUR_IDS.evaluateResultsDetailsDialog),
          },
        }}
      >
        <Details
          annotationId={annotationId || undefined}
          onClose={handleCloseDetails}
          onRerunComplete={() => setAction(null)}
          rerunOnMount={action === "rerun"}
        />
      </Dialog>
    </>
  );
};
