import { createContext, useContext, useEffect, useState } from "react";
import * as api from "../Api/Api";
import { toast } from "react-toastify";
import { useNavigate } from "react-router-dom";

export const AppContext = createContext();
export const useAppContext = () => useContext(AppContext);

export function ContextProvider({ children }) {
  const [userSeats, setUserSeats] = useState([]);
  const [reservedSeats, setReservedSeats] = useState([]);
  const [seatLayout, setSeatLayout] = useState([]);
  const [isLoading, setIsLoading] = useState(false);
  const [seatLimit, setSeatLimit] = useState(
    Number(sessionStorage.getItem("seatLimit")) || 0
  );
  const navigate = useNavigate();

  console.log(reservedSeats);

  const loginOrRegister = async ({ mobile, name }) => {
    try {
      const user = await api.loginUser(mobile);
      if (!user) {
        console.log("registering:", mobile, name);
        const response = await api.register({ mobile, name });
        console.log("Registered:", response);
        sessionStorage.setItem("userId", response?.id);
        await getAllReservedSeats();
        navigate("/seat-limit");
        return response;
      } else {
        sessionStorage.setItem("userId", user?.id);
        const response = await getAllReservedSeats();
        const userSelectedSeats = response.find((e) => e.userId == user?.id);
        sessionStorage.setItem(
          "seatLimit",
          userSelectedSeats?.seats?.length || 0
        );
        navigate("/booking");
        return user;
      }
    } catch (err) {
      toast.error(err.message);
    }
  };

  const addOrUpdateSeats = async ({ id, seats }) => {
    try {
      const validSeats = seats.filter((s) => typeof s === "string" && s.trim());
      if (validSeats.length === 0) {
        toast.error("No valid seats selected.");
        return;
      }

      const latestReserved = await api.getReservedSeats();

      const conflictingSeats = validSeats.filter(
        (seat) => latestReserved.includes(seat) && !userSeats.includes(seat)
      );

      if (conflictingSeats.length > 0) {
        toast.error(
          `Seats already taken: ${conflictingSeats.join(
            ", "
          )}. Please choose different seats.`
        );
        return;
      }

      let response;
      if (!userSeats.length) {
        response = await api.saveSeat({ id, seats: validSeats });
        setReservedSeats((prev) => [...prev, ...validSeats]);
        setUserSeats(validSeats);
      } else {
        response = await api.updateSeat({ id, seats: validSeats });
        setUserSeats(response.seats);
      }

      const [allReserved, userReserved] = await Promise.all([
        api.getReservedSeats(),
        api.getUserReservedSeats(id),
      ]);
      setReservedSeats(allReserved);
      setUserSeats(userReserved);
    } catch (err) {
      toast.error(err.message || "Something went wrong.");
    }
  };

  const getAllReservedSeats = async () => {
    setIsLoading(false);
    try {
      const userId = sessionStorage.getItem("userId");
      const reserved = await api.getReservedSeats();
      const userReserved = await api.getUserReservedSeats(userId);

      setReservedSeats(reserved);
      setUserSeats(userReserved);
    } catch (err) {
      toast.error(err.message);
    }
  };

  const getSeatLayout = async () => {
    setIsLoading(false);
    try {
      const response = await api.getSeatLayout();
      setSeatLayout(response);
      setIsLoading(true);
    } catch (err) {
      toast.error(err.message);
    }
  };

  useEffect(() => {
    const storedLimit = Number(sessionStorage.getItem("seatLimit")) || 0;
    if (storedLimit !== seatLimit) {
      setSeatLimit(storedLimit);
    }
    getAllReservedSeats();
  }, []);
  console.log("state reserved", reservedSeats);
  console.log("Selected Seats:", reservedSeats.length);

  const value = {
    userSeats,
    reservedSeats,
    isLoading,
    seatLayout,
    loginOrRegister,
    addOrUpdateSeats,
    getAllReservedSeats,
    getSeatLayout,
  };

  return <AppContext.Provider value={value}>{children}</AppContext.Provider>;
}
