"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import type { RecommendedProduct } from "@/app/actions/get-event-recommendations";
import type { EventAddon } from "@/lib/event-addons";
import { formatEuro } from "@/lib/utils/money";
import { EventThemeStep, type EventThemeStepDraft } from "./event-theme-step";

interface Props {
  products: RecommendedProduct[];
  guestCount: number;
  selectedAddons: EventAddon[];
  initialDrafts?: Record<string, EventThemeStepDraft>;
  onDraftChange?: (drafts: Record<string, EventThemeStepDraft>) => void;
  onSubmit: (drafts: Record<string, EventThemeStepDraft>) => Promise<void>;
}

function getProductUnitPrice(product: RecommendedProduct) {
  return product.salePriceCents || product.priceCents || 0;
}

function createDefaultDraft(product: RecommendedProduct): EventThemeStepDraft {
  const supportsThemeChoice = product.themeOptions.length > 0 && product.supportsCustomTheme !== false;

  return {
    theme: supportsThemeChoice ? product.themeOptions[0] || undefined : undefined,
    usesCustomTheme: false,
    customizations: {},
  };
}

function getDraftSignature(draft?: EventThemeStepDraft) {
  if (!draft) {
    return "";
  }

  return JSON.stringify({
    theme: draft.theme?.trim() || "",
    usesCustomTheme: draft.usesCustomTheme,
    customizations: Object.entries(draft.customizations || {})
      .sort(([leftKey], [rightKey]) => leftKey.localeCompare(rightKey))
      .map(([key, value]) => [
        key,
        {
          label: value?.label || "",
          value: value?.value || "",
          priceCents: typeof value?.priceCents === "number" ? value.priceCents : undefined,
        },
      ]),
  });
}

export function EventThemesStep({
  products,
  guestCount,
  selectedAddons,
  initialDrafts,
  onDraftChange,
  onSubmit,
}: Props) {
  const [drafts, setDrafts] = useState<Record<string, EventThemeStepDraft>>({});
  const [submitError, setSubmitError] = useState<string | null>(null);
  const [isSubmitting, setIsSubmitting] = useState(false);

  useEffect(() => {
    setDrafts((current) => {
      const nextEntries = products.map((product) => [
        product.handle,
        current[product.handle] || initialDrafts?.[product.handle] || createDefaultDraft(product),
      ] as const);
      const next = Object.fromEntries(nextEntries);

      const sameLength = Object.keys(current).length === nextEntries.length;
      const sameKeys = sameLength && nextEntries.every(([handle, draft]) => current[handle] === draft);
      return sameKeys ? current : next;
    });
  }, [initialDrafts, products]);

  useEffect(() => {
    onDraftChange?.(drafts);
  }, [drafts, onDraftChange]);

  const selectedAddonsTotal = useMemo(
    () => selectedAddons.reduce((total, addon) => total + addon.priceCents, 0),
    [selectedAddons],
  );

  const totalPrice = useMemo(() => {
    return products.reduce((total, product) => {
      return total + (getProductUnitPrice(product) + selectedAddonsTotal) * guestCount;
    }, 0);
  }, [guestCount, products, selectedAddonsTotal]);

  const productsSubtotal = useMemo(() => {
    return products.reduce((total, product) => total + getProductUnitPrice(product) * guestCount, 0);
  }, [guestCount, products]);

  const addonsSubtotal = selectedAddonsTotal * guestCount * products.length;

  const handleProductDraftChange = useCallback((productHandle: string, draft: EventThemeStepDraft) => {
    const nextSignature = getDraftSignature(draft);

    setDrafts((current) => {
      if (getDraftSignature(current[productHandle]) === nextSignature) {
        return current;
      }

      return {
        ...current,
        [productHandle]: draft,
      };
    });
  }, []);

  const draftChangeHandlers = useMemo(() => {
    return Object.fromEntries(
      products.map((product) => [
        product.handle,
        (draft: EventThemeStepDraft) => {
          handleProductDraftChange(product.handle, draft);
        },
      ]),
    ) as Record<string, (draft: EventThemeStepDraft) => void>;
  }, [handleProductDraftChange, products]);

  const handleSubmit = async () => {
    if (products.length === 0) {
      setSubmitError("Veuillez sélectionner au moins un produit.");
      return;
    }

    setIsSubmitting(true);
    setSubmitError(null);

    try {
      await onSubmit(drafts);
    } catch (error) {
      console.error("Error adding event products to cart:", error);
      setSubmitError(error instanceof Error ? error.message : "Impossible d'ajouter ces produits au panier.");
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <div className="space-y-6">
      <div>
        <h2 className="mb-2 font-serif text-2xl text-[var(--foreground)]">Choisissez vos thèmes</h2>
        <p className="text-sm text-[var(--muted)]">
          Finalisez chacun de vos produits avec un thème existant ou une demande sur mesure.
        </p>
      </div>

      <div className="rounded-2xl border border-[var(--line)] bg-[#faf7f5] p-4">
        <div className="space-y-3">
          <div className="flex items-start justify-between gap-4">
            <div>
              <p className="font-semibold text-[var(--foreground)]">
                {products.length} produit{products.length > 1 ? "s" : ""} sélectionné{products.length > 1 ? "s" : ""}
              </p>
              <p className="text-sm text-[var(--muted)]">Quantité par produit: {guestCount}</p>
              {selectedAddons.length > 0 ? (
                <p className="mt-2 text-sm text-[var(--muted)]">
                  Suppléments appliqués à chaque produit: {selectedAddons.map((addon) => addon.label).join(", ")}
                </p>
              ) : null}
            </div>
            <p className="text-lg font-bold text-[var(--accent-3)]">{formatEuro(totalPrice)}</p>
          </div>
          <div className="space-y-2 border-t border-[var(--line)] pt-3 text-sm">
            <div className="flex justify-between gap-4">
              <span className="text-[var(--muted)]">Produits</span>
              <span className="font-medium text-[var(--foreground)]">{formatEuro(productsSubtotal)}</span>
            </div>
            {addonsSubtotal > 0 ? (
              <div className="flex justify-between gap-4">
                <span className="text-[var(--muted)]">Suppléments</span>
                <span className="font-medium text-[var(--foreground)]">{formatEuro(addonsSubtotal)}</span>
              </div>
            ) : null}
          </div>
        </div>
      </div>

      <div className="space-y-4">
        {products.map((product) => (
          <div key={product.handle} className="rounded-[1.6rem] border border-[var(--line)] bg-white p-4 md:p-5">
            <div className="mb-4 flex items-center justify-between gap-3">
              <div>
                <p className="font-serif text-xl text-[var(--foreground)]">{product.title}</p>
                <p className="text-sm text-[var(--muted)]">Configuration du thème</p>
              </div>
              <p className="text-sm font-semibold text-[var(--accent-3)]">
                {formatEuro((getProductUnitPrice(product) + selectedAddonsTotal) * guestCount)}
              </p>
            </div>

            <EventThemeStep
              product={product}
              guestCount={guestCount}
              selectedAddons={selectedAddons}
              initialTheme={drafts[product.handle]?.theme}
              initialUsesCustomTheme={drafts[product.handle]?.usesCustomTheme}
              initialCustomizations={drafts[product.handle]?.customizations}
              mode="embedded"
              showSubmitButton={false}
              onDraftChange={draftChangeHandlers[product.handle]}
            />
          </div>
        ))}
      </div>

      {submitError ? (
        <div className="rounded-lg border border-[#ffd4d4] bg-[#fff5f5] p-4 text-sm text-[#a21717]">
          {submitError}
        </div>
      ) : null}

      <button
        onClick={handleSubmit}
        disabled={isSubmitting || products.length === 0}
        className="w-full rounded-full bg-[var(--accent-3)] px-6 py-3 font-semibold text-white hover:bg-[var(--accent-2)] transition disabled:opacity-50 disabled:cursor-not-allowed"
      >
        {isSubmitting
          ? "Ajout en cours..."
          : `Ajouter ${products.length} produit${products.length > 1 ? "s" : ""} au panier`}
      </button>
    </div>
  );
}
