"use client";

import { useEffect, useState } from "react";

import { useRouter } from "next/navigation";

import { useLanguage } from "@/app/context/LanguageContext";
import { toContentLang } from "@/app/i18n/locales";

import {
  getChoghadiya,
  getFestivals,
  getHora,
  getSunMoonTimings,
  getTodayPanchang,
  PanchangLocation,
} from "@/app/lib/panchang";

import {
  AnyObject,
  BALAM_ELEMENTS,
  MUHURAT_ELEMENTS,
  SAMVAT_ELEMENTS,
  extractField,
  formatSamvat,
  getChoghadiyaRows,
  getFestivalRows,
  getHoraRows,
  getPlanetRows,
  isChoghadiyaShape,
  isHoraShape,
  isSunMoonShape,
  isTodayShape,
  parseDateOnly,
  unwrapUntil,
} from "@/app/lib/panchangParse";

/*
|--------------------------------------------------------------------------
| Shared Panchang Data Hook
|--------------------------------------------------------------------------
|
| Fetches today/sun-moon/choghadiya/hora/festivals in parallel for a
| given date + location and returns fully-parsed rows, ready to render.
| `location` must be a stable reference (e.g. React state) — a fresh
| object literal on every render will cause a refetch loop.
|
*/

export function usePanchangData(
  date: string,
  location: PanchangLocation,
  redirectPath: string,
) {
  const router = useRouter();

  const { locale } = useLanguage();

  const contentLang = toContentLang(locale);

  const [loading, setLoading] = useState(true);

  const [error, setError] = useState("");

  const [todayData, setTodayData] = useState<AnyObject | null>(null);

  const [sunMoonData, setSunMoonData] = useState<AnyObject | null>(null);

  const [choghadiyaData, setChoghadiyaData] = useState<AnyObject | null>(null);

  const [horaData, setHoraData] = useState<AnyObject | null>(null);

  const [festivalsData, setFestivalsData] = useState<AnyObject | null>(null);

  useEffect(() => {
    let cancelled = false;

    async function loadPanchang() {
      try {
        setLoading(true);

        setError("");

        const [today, sunMoon, choghadiya, hora, festivals] = await Promise.all([
          getTodayPanchang(date, location, contentLang),
          getSunMoonTimings(date, location, contentLang),
          getChoghadiya(date, location, contentLang),
          getHora(date, location, contentLang),
          getFestivals(date, location, contentLang),
        ]);

        if (cancelled) {
          return;
        }

        if (
          !today.authenticated ||
          !sunMoon.authenticated ||
          !choghadiya.authenticated ||
          !hora.authenticated ||
          !festivals.authenticated
        ) {
          router.replace(`/signin?redirect=${redirectPath}`);

          return;
        }

        if (!today.success && !sunMoon.success) {
          setError(today.message || sunMoon.message || "Unable to load panchang.");
        }

        setTodayData(today.success ? today.data : null);
        setSunMoonData(sunMoon.success ? sunMoon.data : null);
        setChoghadiyaData(choghadiya.success ? choghadiya.data : null);
        setHoraData(hora.success ? hora.data : null);
        setFestivalsData(festivals.success ? festivals.data : null);
      } catch (err) {
        console.error("Panchang load error:", err);

        if (!cancelled) {
          setError("Unable to load panchang. Please try again.");
        }
      } finally {
        if (!cancelled) {
          setLoading(false);
        }
      }
    }

    loadPanchang();

    return () => {
      cancelled = true;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [date, location, contentLang, router]);

  const today = unwrapUntil(todayData, isTodayShape);

  /*
   * A handful of fields aren't flat top-level keys in the real
   * "today" response — paksha/moon sign/sun sign/samvat live
   * nested under advanced_details/rasi/sun_position. Flatten
   * them onto virtual keys so the generic alias lookups still
   * find them.
   */

  const advancedDetails = today?.advanced_details || {};

  const years = advancedDetails?.years || {};

  const derivedToday: AnyObject = {
    ...today,
    paksha: today?.paksha ?? advancedDetails?.masa?.paksha,
    moon_sign: today?.moon_sign ?? today?.rasi?.name,
    sun_sign: today?.sun_sign ?? today?.sun_position?.zodiac,
    shaka_samvat: today?.shaka_samvat ?? formatSamvat(years?.saka, years?.saka_samvaat_name),
    vikram_samvat: today?.vikram_samvat ?? formatSamvat(years?.vikram_samvaat, years?.vikram_samvaat_name),
  };

  const sunMoon = unwrapUntil(sunMoonData, isSunMoonShape);

  /*
   * The real sun-moon response nests the actual time one level
   * deeper than the wrapper key, e.g.
   * { sunrise: { bot_response, sun_rise: "6:06 AM" }, ... } —
   * fall back to the "today" response's advanced_details (which
   * has flat sun_rise/sun_set/moon_rise/moon_set) if that shape
   * doesn't match.
   */

  const derivedSunMoon: AnyObject = {
    ...sunMoon,
    sunrise: sunMoon?.sunrise?.sun_rise ?? sunMoon?.sun_rise ?? advancedDetails?.sun_rise,
    sunset: sunMoon?.sunset?.sun_set ?? sunMoon?.sun_set ?? advancedDetails?.sun_set,
    moonrise: sunMoon?.moonrise?.moon_rise ?? sunMoon?.moon_rise ?? advancedDetails?.moon_rise,
    moonset: sunMoon?.moonset?.moon_set ?? sunMoon?.moon_set ?? advancedDetails?.moon_set,
  };

  const choghadiya = unwrapUntil(choghadiyaData, isChoghadiyaShape);

  const hora = unwrapUntil(horaData, isHoraShape);

  const festivals = getFestivalRows(festivalsData);

  const dateObj = parseDateOnly(date);

  const dateLabel = dateObj
    ? dateObj.toLocaleDateString("en-IN", {
        weekday: "long",
        day: "2-digit",
        month: "long",
        year: "numeric",
      })
    : date;

  const choghadiyaRows = getChoghadiyaRows(choghadiya);

  const horaRows = getHoraRows(hora);

  const muhuratRows = MUHURAT_ELEMENTS.map((def) => ({
    label: def.label,
    value: extractField(derivedToday, def.aliases),
  })).filter((row) => row.value !== undefined);

  const balamRows = BALAM_ELEMENTS.map((def) => ({
    label: def.label,
    value: extractField(derivedToday, def.aliases),
  })).filter((row) => row.value !== undefined);

  const samvatRows = SAMVAT_ELEMENTS.map((def) => ({
    label: def.label,
    value: extractField(derivedToday, def.aliases),
  })).filter((row) => row.value !== undefined);

  const planetRows = getPlanetRows(today);

  return {
    loading,
    error,
    today,
    derivedToday,
    derivedSunMoon,
    dateLabel,
    choghadiyaRows,
    horaRows,
    festivals,
    muhuratRows,
    balamRows,
    samvatRows,
    planetRows,
  };
}
