import { useEffect, useMemo, useState } from "preact/hooks";
import OfferModalShell from "../modals/OfferModalShell.jsx";

import PlanSection from "../modals/sections/PlanSection.jsx";
import DecoderSection from "../modals/sections/DecoderSection.jsx";
import TvAddonsSection from "../modals/sections/TvAddonsSection.jsx";
import PhoneSection from "../modals/sections/PhoneSection.jsx";
import AddonsSection from "../modals/sections/AddonsSection.jsx";
import SummarySection from "../modals/sections/SummarySection.jsx";
import FloatingTotal from "../modals/sections/FloatingTotal.jsx";

import { mapPhoneYamlToPlans, normalizeAddons, normalizeDecoders } from "../../lib/offer-normalize.js";
import { isTvAddonAvailableForPkg, hasTvTermPricing, getAddonUnitPrice } from "../../lib/offer-pricing.js";
import { saveOfferToLocalStorage } from "../../lib/offer-payload.js";

import "../../styles/modal.css";
import "../../styles/addons.css";

export default function JamboxAddonsModal({
  isOpen,
  onClose,
  pkg,

  phoneCards = [],
  tvAddons = [],
  addons = [],
  decoders = [],

  cenaOpis = "zł/mies.",
}) {
  const phonePlans = useMemo(() => mapPhoneYamlToPlans(phoneCards), [phoneCards]);
  const tvAddonsList = useMemo(() => normalizeAddons(tvAddons), [tvAddons]);
  const addonsList = useMemo(() => normalizeAddons(addons), [addons]);
  const decodersList = useMemo(() => normalizeDecoders(decoders), [decoders]);

  const tvAddonsVisible = useMemo(() => {
    if (!pkg) return [];
    return tvAddonsList.filter((a) => isTvAddonAvailableForPkg(a, pkg));
  }, [tvAddonsList, pkg]);

  const [selectedPhoneId, setSelectedPhoneId] = useState(null);
  const [selectedDecoderId, setSelectedDecoderId] = useState(null);
  const [selectedQty, setSelectedQty] = useState({});
  const [tvTerm, setTvTerm] = useState({}); // { [id]: "12m" | "bezterminowo" }

  const [openSections, setOpenSections] = useState({
    base: true,
    decoder: false,
    tv: false,
    phone: false,
    addons: false,
    summary: false,
  });

  const toggleSection = (key) => {
    setOpenSections((prev) => {
      const nextOpen = !prev[key];
      return {
        base: false,
        decoder: false,
        tv: false,
        phone: false,
        addons: false,
        summary: false,
        [key]: nextOpen,
      };
    });
  };

  useEffect(() => {
    if (!isOpen) return;

    setSelectedPhoneId(null);
    setSelectedQty({});
    setTvTerm({});

    const d0 =
      (Array.isArray(decodersList) && decodersList.find((d) => Number(d.cena) === 0)) ||
      (Array.isArray(decodersList) ? decodersList[0] : null);
    setSelectedDecoderId(d0 ? String(d0.id) : null);

    setOpenSections({
      base: true,
      decoder: false,
      tv: false,
      phone: false,
      addons: false,
      summary: false,
    });
  }, [isOpen, pkg?.id, decodersList]);

  if (!isOpen || !pkg) return null;

  const basePrice = Number(pkg.price_monthly || 0);

  const phonePrice = useMemo(() => {
    if (!selectedPhoneId) return 0;
    const p = phonePlans.find((x) => String(x.id) === String(selectedPhoneId));
    return Number(p?.price_monthly || 0);
  }, [selectedPhoneId, phonePlans]);

  const decoderPrice = useMemo(() => {
    if (!selectedDecoderId) return 0;
    const d = decodersList.find((x) => String(x.id) === String(selectedDecoderId));
    return Number(d?.cena || 0);
  }, [selectedDecoderId, decodersList]);

  const tvAddonsPrice = useMemo(() => {
    return tvAddonsVisible.reduce((sum, a) => {
      const qty = Number(selectedQty[a.id] || 0);
      if (qty <= 0) return sum;

      const termPricing = hasTvTermPricing(a, pkg);
      const term = tvTerm[a.id] || "12m";
      const unit = getAddonUnitPrice(a, pkg, termPricing ? term : null);

      return sum + qty * unit;
    }, 0);
  }, [selectedQty, tvAddonsVisible, tvTerm, pkg]);

  const addonsOnlyPrice = useMemo(() => {
    return addonsList.reduce((sum, a) => {
      const qty = Number(selectedQty[a.id] || 0);
      const unit = getAddonUnitPrice(a, pkg, null);
      return sum + qty * unit;
    }, 0);
  }, [selectedQty, addonsList, pkg]);

  const totalMonthly = basePrice + phonePrice + decoderPrice + tvAddonsPrice + addonsOnlyPrice;

  function buildOfferPayload() {
    const phone = selectedPhoneId
      ? phonePlans.find((p) => String(p.id) === String(selectedPhoneId))
      : null;

    const decoder = selectedDecoderId
      ? decodersList.find((d) => String(d.id) === String(selectedDecoderId))
      : null;

    const tvChosen = tvAddonsVisible
      .map((a) => {
        const qty = Number(selectedQty[a.id] || 0);
        if (qty <= 0) return null;

        const termPricing = hasTvTermPricing(a, pkg);
        const term = tvTerm[a.id] || "12m";
        const unit = getAddonUnitPrice(a, pkg, termPricing ? term : null);

        return {
          id: a.id,
          nazwa: a.nazwa,
          qty,
          term: termPricing ? term : null,
          unit,
        };
      })
      .filter(Boolean);

    const addonsChosen = addonsList
      .map((a) => {
        const qty = Number(selectedQty[a.id] || 0);
        if (qty <= 0) return null;

        const unit = getAddonUnitPrice(a, pkg, null);
        return { id: a.id, nazwa: a.nazwa, qty, unit };
      })
      .filter(Boolean);

    return {
      createdAt: new Date().toISOString(),
      pkg: { id: pkg?.id ?? null, name: pkg?.name ?? "", price: basePrice },
      phone: phone ? { id: phone.id, name: phone.name, price: phone.price_monthly } : null,
      decoder: decoder ? { id: decoder.id, name: decoder.nazwa, price: decoder.cena } : null,
      tvAddons: tvChosen,
      addons: addonsChosen,
      totals: {
        base: basePrice,
        phone: phonePrice,
        decoder: decoderPrice,
        tv: tvAddonsPrice,
        addons: addonsOnlyPrice,
        total: totalMonthly,
        currencyLabel: cenaOpis,
      },
    };
  }

  const onSend = () => {
    const payload = buildOfferPayload();
    saveOfferToLocalStorage(payload, cenaOpis);
  };

  return (
    <OfferModalShell isOpen={isOpen} onClose={onClose} title={`${pkg.name} — konfiguracja usług`}>
      <PlanSection
        title={pkg.name}
        open={openSections.base}
        onToggle={() => toggleSection("base")}
        price={basePrice}
        cenaOpis={cenaOpis}
        features={pkg.features || []}
      />

      <DecoderSection
        open={openSections.decoder}
        onToggle={() => toggleSection("decoder")}
        cenaOpis={cenaOpis}
        decoders={decodersList}
        selectedDecoderId={selectedDecoderId}
        setSelectedDecoderId={setSelectedDecoderId}
        decoderPrice={decoderPrice}
      />

      <TvAddonsSection
        open={openSections.tv}
        onToggle={() => toggleSection("tv")}
        cenaOpis={cenaOpis}
        pkg={pkg}
        tvAddonsVisible={tvAddonsVisible}
        selectedQty={selectedQty}
        setSelectedQty={setSelectedQty}
        tvTerm={tvTerm}
        setTvTerm={setTvTerm}
        tvAddonsPrice={tvAddonsPrice}
      />

      <PhoneSection
        open={openSections.phone}
        onToggle={() => toggleSection("phone")}
        cenaOpis={cenaOpis}
        phonePlans={phonePlans}
        selectedPhoneId={selectedPhoneId}
        setSelectedPhoneId={setSelectedPhoneId}
        phonePrice={phonePrice}
      />

      <AddonsSection
        open={openSections.addons}
        onToggle={() => toggleSection("addons")}
        cenaOpis={cenaOpis}
        addonsList={addonsList}
        selectedQty={selectedQty}
        setSelectedQty={setSelectedQty}
        addonsPrice={addonsOnlyPrice}
        getUnitPrice={(a) => getAddonUnitPrice(a, pkg, null)}
      />

      <SummarySection
        open={openSections.summary}
        onToggle={() => toggleSection("summary")}
        cenaOpis={cenaOpis}
        totalMonthly={totalMonthly}
        ctaHref="/kontakt"
        onSend={onSend}
        rows={[
          { label: "Pakiet", value: basePrice, showDashIfZero: false },
          { label: "Telefon", value: phonePrice, showDashIfZero: true },
          { label: "Dekoder", value: decoderPrice, showDashIfZero: true },
          { label: "Pakiety premium", value: tvAddonsPrice, showDashIfZero: true },
          { label: "Dodatkowe usługi", value: addonsOnlyPrice, showDashIfZero: true },
        ]}
      />

      <FloatingTotal
        storageKey="fuz_floating_total_pos_tv_v1"
        totalMonthly={totalMonthly}
        cenaOpis={cenaOpis}
      />
    </OfferModalShell>
  );
}
