import { useState, useEffect } from "react";
import {
  Stack,
  Typography,
  Button,
  Accordion,
  AccordionSummary,
  AccordionDetails,
  useTheme,
  TextField,
  Autocomplete,
  TableCell,
  TableContainer,
  Table,
  TableHead,
  TableRow,
  Paper,
  TableBody,
} from "@mui/material";
import { observer } from "mobx-react-lite";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";

import { authInstance, languageStore, selectedCityStore } from "@shared";

type Field<T> = {
  label: string;
  data: keyof T;
  render?: (value: any) => React.ReactNode;
};

type LinkedSightsProps<T> = {
  parentId: string | number;
  fields: Field<T>[];
  setItemsParent?: (items: T[]) => void;
  type: "show" | "edit";
  onUpdate?: () => void;
  disableCreation?: boolean;
  updatedLinkedItems?: T[];
  refresh?: number;
};

export const LinkedSights = <
  T extends { id: number; name: string; [key: string]: any }
>(
  props: LinkedSightsProps<T>
) => {
  const theme = useTheme();

  return (
    <>
      <Accordion sx={{ width: "100%" }}>
        <AccordionSummary
          expandIcon={<ExpandMoreIcon />}
          sx={{
            background: theme.palette.background.paper,
            borderBottom: `1px solid ${theme.palette.divider}`,
            width: "100%",
          }}
        >
          <Typography variant="subtitle1" fontWeight="bold">
            Привязанные достопримечательности
          </Typography>
        </AccordionSummary>

        <AccordionDetails
          sx={{ background: theme.palette.background.paper, width: "100%" }}
        >
          <Stack gap={2} width="100%">
            <LinkedSightsContents {...props} />
          </Stack>
        </AccordionDetails>
      </Accordion>
    </>
  );
};

const LinkedSightsContentsInner = <
  T extends { id: number; name: string; [key: string]: any }
>({
  parentId,
  setItemsParent,
  fields,
  type,
  onUpdate,
  disableCreation = false,
  updatedLinkedItems,
  refresh,
}: LinkedSightsProps<T>) => {
  const { language } = languageStore;

  const [allItems, setAllItems] = useState<T[]>([]);
  const [linkedItems, setLinkedItems] = useState<T[]>([]);
  const [selectedItemId, setSelectedItemId] = useState<number | null>(null);
  const [isLoading, setIsLoading] = useState<boolean>(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {}, [error]);

  const parentResource = "station";
  const childResource = "sight";

  const availableItems = allItems
    .filter((item) => !linkedItems.some((linked) => linked.id === item.id))
    .filter((item) => {
      // Фильтруем по городу из навбара
      const selectedCityId = selectedCityStore.selectedCityId;
      if (selectedCityId && "city_id" in item) {
        return item.city_id === selectedCityId;
      }
      return true;
    })
    .sort((a, b) => a.name.localeCompare(b.name));

  useEffect(() => {
    if (updatedLinkedItems) {
      setLinkedItems(updatedLinkedItems);
    }
  }, [updatedLinkedItems]);

  useEffect(() => {
    setItemsParent?.(linkedItems);
  }, [linkedItems, setItemsParent]);

  const linkItem = () => {
    if (selectedItemId !== null) {
      setError(null);
      const requestData = {
        sight_id: selectedItemId,
      };

      authInstance
        .post(`/${parentResource}/${parentId}/${childResource}`, requestData)
        .then(() => {
          const newItem = allItems.find((item) => item.id === selectedItemId);
          if (newItem) {
            setLinkedItems([...linkedItems, newItem]);
          }
          setSelectedItemId(null);
          onUpdate?.();
        })
        .catch((error) => {
          console.error("Error linking sight:", error);
          setError("Failed to link sight");
        });
    }
  };

  const deleteItem = (itemId: number) => {
    setError(null);
    authInstance
      .delete(`/${parentResource}/${parentId}/${childResource}`, {
        data: { [`${childResource}_id`]: itemId },
      })
      .then(() => {
        setLinkedItems(linkedItems.filter((item) => item.id !== itemId));
        onUpdate?.();
      })
      .catch((error) => {
        console.error("Error deleting sight:", error);
        setError("Failed to delete sight");
      });
  };

  useEffect(() => {
    if (parentId) {
      setIsLoading(true);
      setError(null);
      authInstance
        .get(`/${parentResource}/${parentId}/${childResource}`)
        .then((response) => {
          setLinkedItems(response?.data || []);
        })
        .catch((error) => {
          console.error("Error fetching linked sights:", error);
          setError("Failed to load linked sights");
          setLinkedItems([]);
        })
        .finally(() => {
          setIsLoading(false);
        });
    }
  }, [parentId, language, refresh]);

  useEffect(() => {
    if (type === "edit") {
      setError(null);
      authInstance
        .get(`/${childResource}`)
        .then((response) => {
          setAllItems(response?.data || []);
        })
        .catch((error) => {
          console.error("Error fetching all sights:", error);
          setError("Failed to load available sights");
          setAllItems([]);
        });
    }
  }, [type]);

  return (
    <>
      {linkedItems?.length > 0 && (
        <TableContainer component={Paper} sx={{ width: "100%" }}>
          <Table sx={{ width: "100%" }}>
            <TableHead>
              <TableRow>
                <TableCell key="id" width="60px">
                  №
                </TableCell>
                {fields.map((field) => (
                  <TableCell key={String(field.data)}>{field.label}</TableCell>
                ))}
                {type === "edit" && (
                  <TableCell width="120px">Действие</TableCell>
                )}
              </TableRow>
            </TableHead>

            <TableBody>
              {linkedItems.map((item, index) => (
                <TableRow key={item.id} hover>
                  <TableCell>{index + 1}</TableCell>
                  {fields.map((field, idx) => (
                    <TableCell key={String(field.data) + String(idx)}>
                      {field.render
                        ? field.render(item[field.data])
                        : item[field.data]}
                    </TableCell>
                  ))}
                  {type === "edit" && (
                    <TableCell>
                      <Button
                        variant="outlined"
                        color="error"
                        size="small"
                        onClick={(e) => {
                          e.stopPropagation();
                          deleteItem(item.id);
                        }}
                      >
                        Отвязать
                      </Button>
                    </TableCell>
                  )}
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </TableContainer>
      )}

      {linkedItems.length === 0 && !isLoading && (
        <Typography color="textSecondary" textAlign="center" py={2}>
          Достопримечательности не найдены
        </Typography>
      )}

      {type === "edit" && !disableCreation && (
        <Stack gap={2} mt={2}>
          <Typography variant="subtitle1">
            Добавить достопримечательность
          </Typography>
          <Autocomplete
            fullWidth
            value={
              availableItems?.find((item) => item.id === selectedItemId) || null
            }
            onChange={(_, newValue) => setSelectedItemId(newValue?.id || null)}
            options={availableItems}
            getOptionLabel={(item) => String(item.name)}
            renderInput={(params) => (
              <TextField
                {...params}
                label="Выберите достопримечательность"
                fullWidth
              />
            )}
            isOptionEqualToValue={(option, value) => option.id === value?.id}
            filterOptions={(options, { inputValue }) => {
              const searchWords = inputValue
                .toLowerCase()
                .split(" ")
                .filter(Boolean);
              return options.filter((option) => {
                const optionWords = String(option.name)
                  .toLowerCase()
                  .split(" ");
                return searchWords.every((searchWord) =>
                  optionWords.some((word) => word.startsWith(searchWord))
                );
              });
            }}
            renderOption={(props, option) => (
              <li {...props} key={option.id}>
                {String(option.name)}
              </li>
            )}
          />

          <Button
            variant="contained"
            onClick={linkItem}
            disabled={!selectedItemId}
            sx={{ alignSelf: "flex-start" }}
          >
            Добавить
          </Button>
        </Stack>
      )}

      {isLoading && (
        <Typography color="textSecondary" textAlign="center" py={2}>
          Загрузка...
        </Typography>
      )}

      {error && (
        <Typography color="error" textAlign="center" py={2}>
          {error}
        </Typography>
      )}
    </>
  );
};

export const LinkedSightsContents = observer(
  LinkedSightsContentsInner
) as typeof LinkedSightsContentsInner;
