import { DataGrid, GridColDef, GridRenderCellParams } from "@mui/x-data-grid";
import { ruRU } from "@mui/x-data-grid/locales";
import { authStore, languageStore, cityStore, countryStore, SearchInput } from "@shared";
import { useEffect, useState, useMemo } from "react";
import { observer } from "mobx-react-lite";
import { Pencil, Trash2, Minus } from "lucide-react";
import { useNavigate } from "react-router-dom";
import { CreateButton, DeleteModal, LanguageSwitcher } from "@widgets";
import { toast } from "react-toastify";
import { Box, CircularProgress } from "@mui/material";

export const CityListPage = observer(() => {
  const { cities, getCities, deleteCity } = cityStore;
  const navigate = useNavigate();
  const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
  const [isBulkDeleteModalOpen, setIsBulkDeleteModalOpen] = useState(false);
  const [rowId, setRowId] = useState<number | null>(null);
  const [ids, setIds] = useState<number[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [rows, setRows] = useState<any[]>([]);
  const [paginationModel, setPaginationModel] = useState({
    page: 0,
    pageSize: 50,
  });
  const { language } = languageStore;
  const canWriteCities = authStore.canWrite("cities");
  const [searchQuery, setSearchQuery] = useState("");

  useEffect(() => {
    const fetchData = async () => {
      setIsLoading(true);
      await countryStore.getCountries("ru");
      await countryStore.getCountries("en");
      await countryStore.getCountries("zh");
      await getCities(language);
      setIsLoading(false);
    };
    fetchData();
  }, [language]);

  useEffect(() => {
    let newRows = cities[language]?.data?.map((city) => ({
      id: city.id,
      name: city.name,
      country: city.country_code,
    }));

    let newRows2: any[] = [];
    for (const city of newRows) {
      const name = countryStore.countries[language]?.data?.find(
        (country) => country.code === city.country
      )?.name;
      if (name) {
        newRows2.push(city);
      }
    }

    setRows(newRows2 || []);
  }, [cities, countryStore.countries, language, isLoading]);

  const filteredRows = useMemo(() => {
    const query = searchQuery.trim().toLowerCase();
    if (!query) return rows;
    return rows.filter((row) => {
      const cityName = (row.name ?? "").toLowerCase();
      const countryName = (
        countryStore.countries[language]?.data?.find((c) => c.code === row.country)?.name ?? ""
      ).toLowerCase();
      return cityName.includes(query) || countryName.includes(query);
    });
  }, [rows, searchQuery, countryStore.countries, language]);

  const columns: GridColDef[] = [
    {
      field: "country",
      headerName: "Страна",
      width: 150,
      renderCell: (params: GridRenderCellParams) => {
        return (
          <div className="w-full h-full flex items-center">
            {params.value ? (
              countryStore.countries[language]?.data?.find(
                (country) => country.code === params.value
              )?.name
            ) : (
              <Minus size={20} className="text-red-500" />
            )}
          </div>
        );
      },
    },
    {
      field: "name",
      headerName: "Название",
      flex: 1,
      renderCell: (params: GridRenderCellParams) => {
        return (
          <div className="w-full h-full flex items-center">
            {params.value ? (
              params.value
            ) : (
              <Minus size={20} className="text-red-500" />
            )}
          </div>
        );
      },
    },
    ...(authStore.canWrite("cities") ? [{
      field: "actions",
      headerName: "Действия",
      align: "center" as const,
      headerAlign: "center" as const,
      width: 200,
      sortable: false,
      renderCell: (params: GridRenderCellParams) => (
        <div className="flex h-full gap-7 justify-center items-center">
          <button title="Редактировать" onClick={() => navigate(`/city/${params.row.id}/edit`)}>
            <Pencil size={20} className="text-blue-500" />
          </button>
          <button
            title="Удалить"
            onClick={(e) => {
              e.stopPropagation();
              setIsDeleteModalOpen(true);
              setRowId(params.row.id);
            }}
          >
            <Trash2 size={20} className="text-red-500" />
          </button>
        </div>
      ),
    }] : []),
  ];

  return (
    <>
      <LanguageSwitcher />

      <div className="w-full">
        <div className="flex justify-between items-center mb-10">
          <h1 className="text-2xl">Города</h1>
          {canWriteCities && (
            <CreateButton
              label="Создать город"
              path="/city/create"
            />
          )}
        </div>

        {canWriteCities && ids.length > 0 && (
          <div className="flex justify-end mb-5 duration-300">
            <button
              className="px-4 py-2 bg-red-500 text-white rounded flex gap-2 items-center"
              onClick={() => setIsBulkDeleteModalOpen(true)}
            >
              <Trash2 size={20} className="text-white" /> Удалить выбранные (
              {ids.length})
            </button>
          </div>
        )}

        {rows.length > 0 && (
          <SearchInput value={searchQuery} onChange={setSearchQuery} />
        )}

        <DataGrid
          rows={filteredRows}
          columns={columns}
          checkboxSelection={canWriteCities}
          disableRowSelectionExcludeModel
          disableRowSelectionOnClick
          onRowDoubleClick={(params) => {
            if (canWriteCities) {
              navigate(`/city/${params.id}/edit`);
            }
          }}
          loading={isLoading}
          paginationModel={paginationModel}
          onPaginationModelChange={setPaginationModel}
          pageSizeOptions={[50]}
          localeText={ruRU.components.MuiDataGrid.defaultProps.localeText}
          onRowSelectionModelChange={
            canWriteCities
              ? (newSelection: any) => {
                  if (Array.isArray(newSelection)) {
                    const selectedIds = newSelection.map(
                      (id: string | number) => Number(id)
                    );
                    setIds(selectedIds);
                  } else if (
                    newSelection &&
                    typeof newSelection === "object" &&
                    "ids" in newSelection
                  ) {
                    const idsSet = newSelection.ids as Set<string | number>;
                    const selectedIds = Array.from(idsSet).map(
                      (id: string | number) => Number(id)
                    );
                    setIds(selectedIds);
                  } else {
                    setIds([]);
                  }
                }
              : undefined
          }
          slots={{
            noRowsOverlay: () => (
              <Box sx={{ mt: 5, textAlign: "center", color: "text.secondary" }}>
                {isLoading ? (
                  <CircularProgress size={20} />
                ) : (
                  "Нет городов"
                )}
              </Box>
            ),
          }}
        />
      </div>

      <DeleteModal
        open={isDeleteModalOpen}
        onDelete={async () => {
          if (rowId) {
            await deleteCity(rowId.toString());
            toast.success("Город успешно удален");
          }
          setIsDeleteModalOpen(false);
          setRowId(null);
        }}
        onCancel={() => {
          setIsDeleteModalOpen(false);
          setRowId(null);
        }}
      />

      <DeleteModal
        open={isBulkDeleteModalOpen}
        onDelete={async () => {
          await Promise.all(ids.map((id) => deleteCity(id.toString())));
          toast.success("Города успешно удалены");
          getCities(language);
          setIsBulkDeleteModalOpen(false);
          setIds([]);
        }}
        onCancel={() => {
          setIsBulkDeleteModalOpen(false);
        }}
      />
    </>
  );
});
