import React, { useState, useEffect } from "react";
import SelectionDialog from "../components/SelectionDialog.jsx";
import { useNavigate } from "react-router-dom";
import { getCoordinates } from "../geocoder.jsx";
import {
  getCities,
  createCity,
  updateCity,
  deleteCity,
  getFederalDistricts,
} from "../api.jsx";

const Cities = () => {
  const [cities, setCities] = useState([]);
  const [federalDistricts, setFederalDistricts] = useState([]);
  const [newCity, setNewCity] = useState({
    name: "",
    federal_district_id: "",
    x_coordinate: "",
    y_coordinate: "",
  });
  const [editingCityId, setEditingCityId] = useState(null);
  const [error, setError] = useState(null);
  const [showDistrictDialog, setShowDistrictDialog] = useState(false);
  const [isGeocodeAvailable, setIsGeocodeAvailable] = useState(false);
  const [isFetchingCoordinates, setIsFetchingCoordinates] = useState(false);
  const navigate = useNavigate();

  useEffect(() => {
    fetchCities();
    fetchFederalDistricts();
  }, []);

  const fetchCities = async () => {
    try {
      const data = await getCities();
      setCities(data);
    } catch (error) {
      if (error.response && error.response.status === 401) {
        navigate("/login");
      }
      console.error("Ошибка при загрузке городов:", error);
    }
  };

  const fetchFederalDistricts = async () => {
    try {
      const data = await getFederalDistricts();
      setFederalDistricts(data);
    } catch (error) {
      if (error.response && error.response.status === 401) {
        navigate("/login");
      }
      console.error("Ошибка при загрузке федеральных округов:", error);
    }
  };

  const handleInputChange = (e) => {
    const { name, value } = e.target;
    setNewCity({ ...newCity, [name]: value });
    if (name === "name") {
      setIsGeocodeAvailable(value.trim() !== "");
    }
  };

  const handleGeocode = async () => {
    try {
      const { name } = newCity;
      const coordinates = await getCoordinates(name);
      if (coordinates) {
        setNewCity({
          ...newCity,
          x_coordinate: coordinates.latitude,
          y_coordinate: coordinates.longitude,
        });
      } else {
        setError("Не удалось найти координаты для данного города.");
      }
    } catch (error) {
      console.error("Ошибка при получении координат:", error);
      setError("Ошибка при попытке получить координаты.");
    }
  };

  const handleSubmit = async (e) => {
    e.preventDefault();

    if (
      !newCity.name ||
      !newCity.federal_district_id ||
      !newCity.x_coordinate ||
      !newCity.y_coordinate
    ) {
      setError("Пожалуйста, заполните все поля.");
      return;
    }

    try {
      if (editingCityId) {
        await updateCity(editingCityId, newCity);
      } else {
        await createCity(newCity);
      }
      fetchCities();
      resetForm();
    } catch (error) {
      console.error("Ошибка при добавлении или обновлении города:", error);
    }
  };

  const handleEdit = (city) => {
    setNewCity({
      name: city.name,
      federal_district_id: city.federal_district_id,
      federal_district_name: city.federal_district_name,
      x_coordinate: city.x_coordinate,
      y_coordinate: city.y_coordinate,
    });
    setIsGeocodeAvailable(true);
    setEditingCityId(city.id);
  };

  const handleDelete = async (cityId) => {
    try {
      await deleteCity(cityId);
      fetchCities();
    } catch (error) {
      console.error("Ошибка при удалении города:", error);
    }
  };

  const resetForm = () => {
    setNewCity({
      name: "",
      federal_district_id: "",
      x_coordinate: "",
      y_coordinate: "",
    });
    setEditingCityId(null);
    setIsGeocodeAvailable(false);
  };

  const handleDialogSelectDistrict = (selectedItem) => {
    setNewCity({
      ...newCity,
      federal_district_id: selectedItem.id,
      federal_district_name: selectedItem.name,
    });
    setShowDistrictDialog(false);
  };

  return (
    <div className="container mt-4">
      <h3>Города</h3>
      <form onSubmit={handleSubmit}>
        <div className="form-group">
          <label htmlFor="cityName">Название города</label>
          <input
            type="text"
            className="form-control"
            id="cityName"
            name="name"
            placeholder="Введите название города"
            value={newCity.name}
            onChange={handleInputChange}
          />
        </div>

        <div className="input-group mb-3">
          <input
            type="text"
            className="form-control"
            id="federalDistrictId"
            name="federalDistrictId"
            placeholder="Выберите федеральный округ"
            value={
              newCity.federal_district_name ? newCity.federal_district_name : ""
            }
            readOnly
            onClick={() => setShowDistrictDialog(true)}
          />
          <div className="input-group-append">
            <button
              type="button"
              className="btn btn-outline-secondary"
              onClick={() => setShowDistrictDialog(true)}
            >
              Выбрать
            </button>
          </div>
        </div>

        <div className="input-group mb-3">
          <input
            type="text"
            className="form-control"
            placeholder="X координата"
            value={newCity.x_coordinate || ""}
            readOnly
          />
        </div>

        <div className="input-group mb-3">
          <input
            type="text"
            className="form-control"
            placeholder="Y координата"
            value={newCity.y_coordinate || ""}
            readOnly
          />
        </div>

        <div className="btn-group mt-3">
          <button
            type="submit"
            className="btn btn-primary"
            disabled={isFetchingCoordinates}
          >
            {editingCityId ? "Обновить" : "Создать"}
          </button>
          <button
            type="button"
            className="btn btn-secondary"
            onClick={resetForm}
            disabled={isFetchingCoordinates}
          >
            Отменить
          </button>
          <button
            type="button"
            className="btn btn-info"
            onClick={handleGeocode}
            disabled={!isGeocodeAvailable || isFetchingCoordinates}
          >
            Узнать координаты
          </button>
        </div>

        {error && (
          <div className="alert alert-danger mt-3" role="alert">
            {error}
          </div>
        )}
      </form>

      <h3 className="mt-5">Список городов</h3>
      <table className="table table-bordered">
        <thead>
          <tr>
            <th>Название</th>
            <th>Федеральный округ</th>
            <th>X координата</th>
            <th>Y координата</th>
            <th>Действия</th>
          </tr>
        </thead>
        <tbody>
          {cities.map((city) => (
            <tr key={city.id}>
              <td>{city.name}</td>
              <td>{city.federal_district_name}</td>
              <td>{city.x_coordinate}</td>
              <td>{city.y_coordinate}</td>
              <td>
                <div className="btn-group">
                  <button
                    className="btn btn-warning"
                    onClick={() => handleEdit(city)}
                  >
                    Изменить
                  </button>
                  <button
                    className="btn btn-danger"
                    onClick={() => handleDelete(city.id)}
                  >
                    Удалить
                  </button>
                </div>
              </td>
            </tr>
          ))}
        </tbody>
      </table>

      <SelectionDialog
        show={showDistrictDialog}
        handleClose={() => setShowDistrictDialog(false)}
        items={federalDistricts}
        columns={[
          { key: "id", label: "ID" },
          { key: "name", label: "Название" },
        ]}
        onSelect={handleDialogSelectDistrict}
      />
    </div>
  );
};

export default Cities;
