import {
  Button,
  Paper,
  TextField,
  Select,
  MenuItem,
  FormControl,
  InputLabel,
  Box,
} from "@mui/material";
import { observer } from "mobx-react-lite";
import { ArrowLeft, Save } from "lucide-react";
import { Loader2 } from "lucide-react";
import { useNavigate, useParams } from "react-router-dom";
import { toast } from "react-toastify";
import {
  carrierStore,
  cityStore,
  authStore,
  mediaStore,
  languageStore,
  isMediaIdEmpty,
  LoadingSpinner,
  selectedCityStore,
} from "@shared";
import { useState, useEffect } from "react";
import { ImageUploadCard, LanguageSwitcher, DeleteModal } from "@widgets";
import {
  SelectMediaDialog,
  PreviewMediaDialog,
  UploadMediaDialog,
} from "@shared";

type ColorFields = {
  main_color: string;
  left_color: string;
  right_color: string;
};

const colorFields = (data: ColorFields) => ({
  main_color: data.main_color,
  left_color: data.left_color,
  right_color: data.right_color,
});

const ColorPickerField = ({
  label,
  value,
  onChange,
}: {
  label: string;
  value: string;
  onChange: (val: string) => void;
}) => (
  <div className="flex items-center gap-3 w-full">
    <div
      className="w-10 h-10 rounded border border-gray-300 flex-shrink-0 cursor-pointer overflow-hidden relative"
      style={{ backgroundColor: value || "#ffffff" }}
    >
      <input
        type="color"
        value={value || "#ffffff"}
        onChange={(e) => onChange(e.target.value)}
        className="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
      />
    </div>
    <TextField
      fullWidth
      label={label}
      value={value}
      placeholder="#000000"
      onChange={(e) => onChange(e.target.value)}
      InputProps={{
        endAdornment: value ? (
          <button
            type="button"
            onClick={() => onChange("")}
            className="text-gray-400 hover:text-gray-600 text-xs px-1"
          >
            ✕
          </button>
        ) : undefined,
      }}
    />
  </div>
);

export const CarrierEditPage = observer(() => {
  const navigate = useNavigate();
  const { id } = useParams();
  const { getCarrier, setEditCarrierData, editCarrierData } = carrierStore;
  const { language } = languageStore;
  const canReadCities = authStore.canRead("cities");

  const [isLoading, setIsLoading] = useState(false);
  const [isLoadingData, setIsLoadingData] = useState(true);
  const [isSelectMediaOpen, setIsSelectMediaOpen] = useState(false);
  const [isUploadMediaOpen, setIsUploadMediaOpen] = useState(false);
  const [isPreviewMediaOpen, setIsPreviewMediaOpen] = useState(false);
  const [mediaId, setMediaId] = useState("");
  const [isDeleteLogoModalOpen, setIsDeleteLogoModalOpen] = useState(false);
  const [initialCityName, setInitialCityName] = useState("");
  const [activeMenuType, setActiveMenuType] = useState<
    "thumbnail" | "watermark_lu" | "watermark_rd" | "image" | null
  >(null);

  useEffect(() => {
    selectedCityStore.setIsLocked(true);
    return () => selectedCityStore.setIsLocked(false);
  }, []);

  useEffect(() => {
    (async () => {
      if (!id) {
        setIsLoadingData(false);
        return;
      }
      setIsLoadingData(true);
      try {
        if (!authStore.me) {
          await authStore.getMeAction().catch(() => undefined);
        }
        if (authStore.canRead("cities")) {
          await cityStore.getCities("ru");
        } else {
          await authStore.fetchMeCities().catch(() => undefined);
        }
        const carrierData = await getCarrier(Number(id));

        if (carrierData) {
          const colors = {
            main_color: carrierData.ru?.main_color || "",
            left_color: carrierData.ru?.left_color || "",
            right_color: carrierData.ru?.right_color || "",
          };
          setEditCarrierData(
            carrierData.ru?.full_name || "",
            carrierData.ru?.short_name || "",
            carrierData.ru?.city_id || 0,
            carrierData.ru?.slogan || "",
            carrierData.ru?.logo || "",
            "ru",
            colors,
          );
          setEditCarrierData(
            carrierData.en?.full_name || "",
            carrierData.en?.short_name || "",
            carrierData.en?.city_id || 0,
            carrierData.en?.slogan || "",
            carrierData.en?.logo || "",
            "en",
          );
          setEditCarrierData(
            carrierData.zh?.full_name || "",
            carrierData.zh?.short_name || "",
            carrierData.zh?.city_id || 0,
            carrierData.zh?.slogan || "",
            carrierData.zh?.logo || "",
            "zh",
          );
          setInitialCityName(carrierData.ru?.city || "");
        }

        await mediaStore.getMedia();
      } finally {
        setIsLoadingData(false);
      }
    })();

    languageStore.setLanguage("ru");
  }, [id]);

  const handleEdit = async () => {
    try {
      setIsLoading(true);
      await carrierStore.editCarrier(Number(id));
      toast.success("Перевозчик успешно обновлен");
      navigate("/carrier");
    } catch (error) {
      toast.error("Ошибка при обновлении перевозчика");
    } finally {
      setIsLoading(false);
    }
  };

  const handleMediaSelect = (media: {
    id: string;
    filename: string;
    media_name?: string;
    media_type: number;
  }) => {
    setEditCarrierData(
      editCarrierData[language].full_name,
      editCarrierData[language].short_name,
      editCarrierData.city_id,
      editCarrierData[language].slogan,
      media.id,
      language,
    );
  };

  const selectedMedia =
    editCarrierData.logo && !isMediaIdEmpty(editCarrierData.logo)
      ? mediaStore.media.find((m) => m.id === editCarrierData.logo)
      : null;
  const effectiveLogoUrl = isMediaIdEmpty(editCarrierData.logo)
    ? null
    : (selectedMedia?.id ?? editCarrierData.logo);

  const baseCities = canReadCities
    ? cityStore.cities["ru"].data
    : authStore.meCities["ru"].map((city) => ({
        id: city.city_id,
        name: city.name,
        country: "",
        country_code: "",
        arms: "",
      }));

  const availableCities =
    editCarrierData.city_id &&
    !baseCities.some((city) => city.id === editCarrierData.city_id)
      ? [
          {
            id: editCarrierData.city_id,
            name: initialCityName || `Город ${editCarrierData.city_id}`,
            country: "",
            country_code: "",
            arms: "",
          },
          ...baseCities,
        ]
      : baseCities;

  if (isLoadingData) {
    return (
      <Box
        sx={{
          display: "flex",
          justifyContent: "center",
          alignItems: "center",
          minHeight: "60vh",
        }}
      >
        <LoadingSpinner message="Загрузка данных перевозчика..." />
      </Box>
    );
  }

  return (
    <Paper className="w-full h-full p-3 flex flex-col gap-10">
      <LanguageSwitcher />
      <div className="flex items-center gap-4">
        <button
          className="flex items-center gap-2"
          onClick={() => navigate(-1)}
        >
          <ArrowLeft size={20} />
          Назад
        </button>
      </div>

      <div className="flex gap-10 items-center mb-5 max-w-[80%] self-start">
        <h1 className="text-3xl break-words">{editCarrierData.ru.full_name}</h1>
      </div>
      <div className="flex flex-col gap-10 w-full items-end">
        <FormControl fullWidth>
          <InputLabel>Город</InputLabel>
          <Select
            value={editCarrierData.city_id || ""}
            label="Город"
            required
            onChange={(e) =>
              setEditCarrierData(
                editCarrierData[language].full_name,
                editCarrierData[language].short_name,
                Number(e.target.value),
                editCarrierData[language].slogan,
                editCarrierData.logo,
                language,
              )
            }
          >
            {availableCities.map((city) => (
              <MenuItem key={city.id} value={city.id}>
                {city.name}
              </MenuItem>
            ))}
          </Select>
        </FormControl>

        <TextField
          fullWidth
          label="Полное название"
          value={editCarrierData[language].full_name}
          required
          onChange={(e) =>
            setEditCarrierData(
              e.target.value,
              editCarrierData[language].short_name,
              editCarrierData.city_id,
              editCarrierData[language].slogan,
              editCarrierData.logo,
              language,
            )
          }
        />

        <TextField
          fullWidth
          label="Короткое название"
          value={editCarrierData[language].short_name}
          required
          onChange={(e) =>
            setEditCarrierData(
              editCarrierData[language].full_name,
              e.target.value,
              editCarrierData.city_id,
              editCarrierData[language].slogan,
              editCarrierData.logo,
              language,
            )
          }
        />

        <TextField
          fullWidth
          label="Слоган"
          value={editCarrierData[language].slogan}
          onChange={(e) =>
            setEditCarrierData(
              editCarrierData[language].full_name,
              editCarrierData[language].short_name,
              editCarrierData.city_id,
              e.target.value,
              editCarrierData.logo,
              language,
            )
          }
        />

        <div className="w-full flex flex-col gap-6">
          <div className="flex flex-col gap-1">
            <ColorPickerField
              label="Основной цвет"
              value={editCarrierData.main_color}
              onChange={(val) =>
                setEditCarrierData(
                  editCarrierData[language].full_name,
                  editCarrierData[language].short_name,
                  editCarrierData.city_id,
                  editCarrierData[language].slogan,
                  editCarrierData.logo,
                  language,
                  { ...colorFields(editCarrierData), main_color: val },
                )
              }
            />
            <p className="text-xs text-gray-500 pl-1">
              Используется в: значки на карте, скопление достопримечательностей
              на карте, информационный виджет
            </p>
          </div>
          <div className="flex flex-col gap-1">
            <ColorPickerField
              label="Левый цвет"
              value={editCarrierData.left_color}
              onChange={(val) =>
                setEditCarrierData(
                  editCarrierData[language].full_name,
                  editCarrierData[language].short_name,
                  editCarrierData.city_id,
                  editCarrierData[language].slogan,
                  editCarrierData.logo,
                  language,
                  { ...colorFields(editCarrierData), left_color: val },
                )
              }
            />
            <p className="text-xs text-gray-500 pl-1">
              Используется в: виджет обращений, боковое меню (фон, список
              остановок), левый виджет достопримечательности
            </p>
          </div>
          <div className="flex flex-col gap-1">
            <ColorPickerField
              label="Правый цвет"
              value={editCarrierData.right_color}
              onChange={(val) =>
                setEditCarrierData(
                  editCarrierData[language].full_name,
                  editCarrierData[language].short_name,
                  editCarrierData.city_id,
                  editCarrierData[language].slogan,
                  editCarrierData.logo,
                  language,
                  { ...colorFields(editCarrierData), right_color: val },
                )
              }
            />
            <p className="text-xs text-gray-500 pl-1">
              Используется в: список достопримечательностей (фон, карточки),
              правый виджет достопримечательности
            </p>
          </div>
        </div>

        <div className="w-full flex flex-col gap-4 max-w-[300px] mx-auto">
          <ImageUploadCard
            title="Логотип перевозчика"
            imageKey="thumbnail"
            imageUrl={effectiveLogoUrl}
            onImageClick={() => {
              setIsPreviewMediaOpen(true);
              setMediaId(effectiveLogoUrl ?? "");
            }}
            onDeleteImageClick={() => {
              setIsDeleteLogoModalOpen(true);
            }}
            onSelectFileClick={() => {
              setActiveMenuType("image");
              setIsSelectMediaOpen(true);
            }}
            setUploadMediaOpen={() => {
              setIsUploadMediaOpen(true);
              setActiveMenuType("image");
            }}
          />
        </div>

        <Button
          variant="contained"
          className="w-min flex gap-2 items-center"
          startIcon={<Save size={20} />}
          onClick={handleEdit}
          disabled={
            isLoading ||
            !editCarrierData[language].full_name ||
            !editCarrierData.city_id
          }
        >
          {isLoading ? (
            <Loader2 size={20} className="animate-spin" />
          ) : (
            "Сохранить"
          )}
        </Button>
      </div>

      <SelectMediaDialog
        open={isSelectMediaOpen}
        onClose={() => setIsSelectMediaOpen(false)}
        onSelectMedia={handleMediaSelect}
        mediaType={1}
      />

      <UploadMediaDialog
        open={isUploadMediaOpen}
        onClose={() => setIsUploadMediaOpen(false)}
        contextObjectName={editCarrierData[language].full_name}
        contextType="carrier"
        afterUpload={handleMediaSelect}
        hardcodeType={activeMenuType}
      />

      <PreviewMediaDialog
        open={isPreviewMediaOpen}
        onClose={() => setIsPreviewMediaOpen(false)}
        mediaId={mediaId}
      />

      <DeleteModal
        open={isDeleteLogoModalOpen}
        onDelete={() => {
          setEditCarrierData(
            editCarrierData[language].full_name,
            editCarrierData[language].short_name,
            editCarrierData.city_id,
            editCarrierData[language].slogan,
            "",
            language,
          );
          setIsDeleteLogoModalOpen(false);
        }}
        onCancel={() => setIsDeleteLogoModalOpen(false)}
        edit
      />
    </Paper>
  );
});
