"use client";

import Image from "next/image";
import { useEffect, useMemo, useRef, useState } from "react";
import type { RecommendedProduct } from "@/app/actions/get-event-recommendations";
import type { EventAddon } from "@/lib/event-addons";
import {
  DEFAULT_CUSTOM_THEME_FIELDS,
  isCustomizationImageValue,
  resolvePersonalizationInputType,
  type ProductPersonalizationField,
} from "@/lib/personalization";
import { formatEuro } from "@/lib/utils/money";

export type SelectedCustomizationValue = {
  label: string;
  value: string;
  priceCents?: number;
};

export type EventThemeStepDraft = {
  theme?: string;
  usesCustomTheme: boolean;
  customizations: Record<string, SelectedCustomizationValue>;
};

function getDraftSignature(draft: EventThemeStepDraft) {
  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,
        },
      ]),
  });
}

function createInitialCustomizations(
  existing?: Record<string, SelectedCustomizationValue>,
): Record<string, SelectedCustomizationValue> {
  return Object.fromEntries(
    DEFAULT_CUSTOM_THEME_FIELDS.map((field) => {
      const current = existing?.[field.key];
      return [
        field.key,
        {
          label: field.label,
          value: current?.value || field.defaultValue || "",
          priceCents: current?.priceCents,
        },
      ];
    }),
  );
}

interface Props {
  product: RecommendedProduct;
  guestCount: number;
  selectedAddons: EventAddon[];
  initialTheme?: string;
  initialUsesCustomTheme?: boolean;
  initialCustomizations?: Record<string, SelectedCustomizationValue>;
  mode?: "standalone" | "embedded";
  showSubmitButton?: boolean;
  submitLabel?: string;
  onDraftChange?: (input: EventThemeStepDraft) => void;
  onSubmit?: (input: EventThemeStepDraft) => Promise<void>;
}

export function EventThemeStep({
  product,
  guestCount,
  selectedAddons,
  initialTheme,
  initialUsesCustomTheme = false,
  initialCustomizations,
  mode = "standalone",
  showSubmitButton = true,
  submitLabel = "Ajouter au panier",
  onDraftChange,
  onSubmit,
}: Props) {
  const customThemeConfig = useMemo(() => {
    return {
      isEnabled: product.customThemeRequest?.isEnabled !== false && product.isCustomizable !== false,
      optionLabel: product.customThemeRequest?.optionLabel?.trim() || "Je personnalise mon thème",
      modalTitle: product.customThemeRequest?.modalTitle?.trim() || "Personnaliser mon thème",
      helperText: product.customThemeRequest?.helperText?.trim() || "",
      modalDescription:
        product.customThemeRequest?.modalDescription?.trim() ||
        "Décrivez votre univers, vos couleurs et vos inspirations pour une création sur mesure.",
    };
  }, [product.customThemeRequest, product.isCustomizable]);

  const supportsThemeChoice = product.themeOptions.length > 0 && product.supportsCustomTheme !== false;
  const hasThemeImages = product.themeDetails.some((theme) => Boolean(theme.imageUrl));
  const [selectedTheme, setSelectedTheme] = useState(() => {
    if (typeof initialTheme === "string" && initialTheme.trim() && !initialUsesCustomTheme) {
      return initialTheme.trim();
    }

    return supportsThemeChoice ? product.themeOptions[0] || "" : "";
  });
  const [usesCustomTheme, setUsesCustomTheme] = useState(initialUsesCustomTheme);
  const [selectedCustomizations, setSelectedCustomizations] = useState<Record<string, SelectedCustomizationValue>>(() =>
    createInitialCustomizations(initialCustomizations),
  );
  const [isCustomThemeModalOpen, setIsCustomThemeModalOpen] = useState(false);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [submitError, setSubmitError] = useState<string | null>(null);
  const [uploadStates, setUploadStates] = useState<Record<string, { pending?: boolean; error?: string | null }>>({});
  const fileInputRefs = useRef<Record<string, HTMLInputElement | null>>({});
  const lastDraftSignatureRef = useRef<string>("");

  const selectedAddonsTotal = selectedAddons.reduce((total, addon) => total + addon.priceCents, 0);
  const totalPrice = ((product.salePriceCents || product.priceCents) + selectedAddonsTotal) * guestCount;
  const selectedThemeValue = usesCustomTheme ? customThemeConfig.optionLabel : selectedTheme.trim();

  const customThemeSummary = useMemo(() => {
    return DEFAULT_CUSTOM_THEME_FIELDS.map((field) => {
      const value = selectedCustomizations[field.key]?.value || "";
      if (!value.trim()) return null;
      return `${field.label}: ${isCustomizationImageValue(value) ? "Image ajoutée" : value}`;
    }).filter((value): value is string => Boolean(value));
  }, [selectedCustomizations]);

  const filteredCustomizations = useMemo(() => {
    return Object.fromEntries(
      Object.entries(selectedCustomizations).filter(([, entry]) => Boolean(entry?.value?.trim())),
    );
  }, [selectedCustomizations]);

  useEffect(() => {
    const nextDraft = {
      theme: selectedThemeValue || undefined,
      usesCustomTheme,
      customizations: selectedCustomizations,
    };
    const nextDraftSignature = getDraftSignature(nextDraft);

    if (lastDraftSignatureRef.current === nextDraftSignature) {
      return;
    }

    lastDraftSignatureRef.current = nextDraftSignature;
    onDraftChange?.(nextDraft);
  }, [onDraftChange, selectedCustomizations, selectedThemeValue, usesCustomTheme]);

  const handleImageUpload = async (field: ProductPersonalizationField, file: File | null) => {
    if (!file) return;

    setUploadStates((current) => ({
      ...current,
      [field.key]: { pending: true, error: null },
    }));

    try {
      const formData = new FormData();
      formData.set("file", file);
      formData.set("fieldKey", field.key);
      formData.set("productHandle", product.handle);

      const response = await fetch("/api/personalization/upload", {
        method: "POST",
        body: formData,
      });

      const payload = (await response.json()) as { ok?: boolean; url?: string; message?: string };
      if (!response.ok || !payload.ok || !payload.url) {
        throw new Error(payload.message || "Upload impossible.");
      }

      setSelectedCustomizations((current) => ({
        ...current,
        [field.key]: { label: field.label, value: payload.url || "" },
      }));
      setUploadStates((current) => ({
        ...current,
        [field.key]: { pending: false, error: null },
      }));
    } catch (error) {
      setUploadStates((current) => ({
        ...current,
        [field.key]: {
          pending: false,
          error: error instanceof Error ? error.message : "Upload impossible.",
        },
      }));
    }
  };

  const renderCustomizationField = (field: ProductPersonalizationField) => {
    const selectedValue = selectedCustomizations[field.key]?.value || "";

    if (field.inputType === "image") {
      const uploadState = uploadStates[field.key];
      const previewUrl = isCustomizationImageValue(selectedValue) ? selectedValue : "";

      return (
        <div key={field.key} className="space-y-2 text-sm">
          {field.showLabel ? <span className="block font-medium text-[var(--foreground)]">{field.label}</span> : null}
          {field.helperText ? <span className="block text-xs text-[var(--muted)]">{field.helperText}</span> : null}
          <input
            ref={(node) => {
              fileInputRefs.current[field.key] = node;
            }}
            type="file"
            accept="image/png,image/jpeg,image/webp,image/heic,image/heif"
            className="hidden"
            onChange={(event) => {
              void handleImageUpload(field, event.target.files?.[0] || null);
              event.currentTarget.value = "";
            }}
          />
          <div
            role="button"
            tabIndex={0}
            onClick={() => fileInputRefs.current[field.key]?.click()}
            onKeyDown={(event) => {
              if (event.key === "Enter" || event.key === " ") {
                event.preventDefault();
                fileInputRefs.current[field.key]?.click();
              }
            }}
            onDragOver={(event) => {
              event.preventDefault();
            }}
            onDrop={(event) => {
              event.preventDefault();
              void handleImageUpload(field, event.dataTransfer.files?.[0] || null);
            }}
            className="rounded-2xl border border-dashed border-[var(--line)] bg-white px-4 py-5 text-center text-sm text-[var(--muted)] transition hover:border-[var(--accent-3)] hover:bg-[#fff8f8]"
          >
            <p className="font-medium text-[var(--foreground)]">
              {uploadState?.pending ? "Upload en cours..." : "Glissez une image ici ou cliquez pour choisir"}
            </p>
            <p className="mt-1 text-xs">PNG, JPG, WEBP, HEIC, HEIF • 10 Mo max</p>
          </div>
          {uploadState?.error ? <p className="text-xs text-[#b42318]">{uploadState.error}</p> : null}
          {previewUrl ? (
            <div className="space-y-2">
              <div className="relative h-28 w-28 overflow-hidden rounded-xl border border-[var(--line)]">
                <Image src={previewUrl} alt={field.label} fill sizes="112px" className="object-cover" unoptimized />
              </div>
              <button
                type="button"
                onClick={() =>
                  setSelectedCustomizations((current) => ({
                    ...current,
                    [field.key]: { label: field.label, value: "" },
                  }))
                }
                className="text-xs font-medium text-[var(--accent-3)]"
              >
                Supprimer cette image
              </button>
            </div>
          ) : null}
        </div>
      );
    }

    if (field.inputType === "color") {
      const displayValue = selectedValue || field.defaultValue || "#d7c2a0";

      return (
        <div key={field.key} className="space-y-2 text-sm">
          {field.showLabel ? <span className="block font-medium text-[var(--foreground)]">{field.label}</span> : null}
          {field.helperText ? <span className="block text-xs text-[var(--muted)]">{field.helperText}</span> : null}
          <div className="flex items-center gap-3 rounded-2xl border border-[var(--line)] bg-white px-3 py-2">
            <input
              type="color"
              value={displayValue}
              onChange={(event) => {
                setSelectedCustomizations((current) => ({
                  ...current,
                  [field.key]: { label: field.label, value: event.target.value },
                }));
              }}
              className="h-11 w-14 cursor-pointer rounded-lg border-0 bg-transparent p-0"
            />
            <div className="space-y-1">
              <p className="text-sm font-medium text-[var(--foreground)]">{displayValue.toUpperCase()}</p>
              <p className="text-xs text-[var(--muted)]">Cliquez pour choisir une couleur</p>
            </div>
          </div>
        </div>
      );
    }

    return (
      <label key={field.key} className="block space-y-1 text-sm">
        {field.showLabel ? <span className="font-medium text-[var(--foreground)]">{field.label}</span> : null}
        {field.helperText ? <span className="text-xs text-[var(--muted)]">{field.helperText}</span> : null}
        {field.inputType === "textarea" ? (
          <textarea
            rows={3}
            value={selectedValue}
            placeholder={field.placeholder || undefined}
            maxLength={field.maxLength || undefined}
            onChange={(event) => {
              setSelectedCustomizations((current) => ({
                ...current,
                [field.key]: { label: field.label, value: event.target.value },
              }));
            }}
            className="w-full rounded-xl border border-[var(--line)] bg-white px-3 py-2 outline-none focus:border-[#f5505080]"
          />
        ) : (
          <input
            type={resolvePersonalizationInputType(field.inputType)}
            value={selectedValue}
            placeholder={field.placeholder || undefined}
            maxLength={field.maxLength || undefined}
            onChange={(event) => {
              setSelectedCustomizations((current) => ({
                ...current,
                [field.key]: { label: field.label, value: event.target.value },
              }));
            }}
            className="w-full rounded-xl border border-[var(--line)] bg-white px-3 py-2 outline-none focus:border-[#f5505080]"
          />
        )}
      </label>
    );
  };

  const handleSubmit = async () => {
    if (!onSubmit) return;

    setIsSubmitting(true);
    setSubmitError(null);

    try {
      await onSubmit({
        theme: selectedThemeValue || undefined,
        usesCustomTheme,
        customizations: usesCustomTheme ? filteredCustomizations : {},
      });
    } catch (error) {
      console.error("Error adding themed product to cart:", error);
      setSubmitError(error instanceof Error ? error.message : "Impossible d'ajouter ce produit au panier.");
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <>
      <div className="space-y-6">
        {mode === "standalone" ? (
          <div>
            <h2 className="mb-2 font-serif text-2xl text-[var(--foreground)]">Choisissez votre thème</h2>
            <p className="text-sm text-[var(--muted)]">
              Finalisez {product.title} avec un thème existant ou une demande sur mesure.
            </p>
          </div>
        ) : null}

        <div className="rounded-2xl border border-[var(--line)] bg-[#faf7f5] p-4">
          <div className="flex items-start justify-between gap-4">
            <div>
              <p className="font-semibold text-[var(--foreground)]">{product.title}</p>
              <p className="text-sm text-[var(--muted)]">Quantité: {guestCount}</p>
              {selectedAddons.length > 0 ? (
                <p className="mt-2 text-sm text-[var(--muted)]">
                  Suppléments: {selectedAddons.map((addon) => addon.label).join(", ")}
                </p>
              ) : null}
            </div>
            <p className="text-lg font-bold text-[var(--accent-3)]">{formatEuro(totalPrice)}</p>
          </div>
        </div>

        {supportsThemeChoice ? (
          <div className="space-y-3">
            <span className="block text-sm font-medium text-[var(--foreground)]">Thèmes suggérés</span>
            {hasThemeImages ? (
              <div className="grid grid-cols-2 gap-3 sm:grid-cols-3">
                {product.themeDetails.map((theme) => {
                  const isSelected = !usesCustomTheme && selectedTheme === theme.title;
                  return (
                    <button
                      key={theme.title}
                      type="button"
                      onClick={() => {
                        setUsesCustomTheme(false);
                        setSelectedTheme(theme.title);
                        setSubmitError(null);
                      }}
                      className={`overflow-hidden rounded-2xl border bg-white text-left transition ${
                        isSelected
                          ? "border-[var(--accent-3)] shadow-[inset_0_0_0_1px_var(--accent-3)]"
                          : "border-[var(--line)] hover:border-[var(--accent-3)] hover:bg-[#fff8f8]"
                      }`}
                    >
                      <div className="relative aspect-square bg-[#f7f2ee]">
                        {theme.imageUrl ? (
                          <Image
                            src={theme.imageUrl}
                            alt={theme.title}
                            fill
                            sizes="(max-width: 640px) 50vw, 33vw"
                            className="object-cover"
                            unoptimized
                          />
                        ) : null}
                      </div>
                      <div className="px-3 py-2">
                        <span className="line-clamp-2 block text-xs font-medium text-[var(--foreground)]">{theme.title}</span>
                      </div>
                    </button>
                  );
                })}
              </div>
            ) : (
              <div className="flex flex-wrap gap-2">
                {product.themeOptions.map((theme) => {
                  const isSelected = !usesCustomTheme && selectedTheme === theme;
                  return (
                    <button
                      key={theme}
                      type="button"
                      onClick={() => {
                        setUsesCustomTheme(false);
                        setSelectedTheme(theme);
                        setSubmitError(null);
                      }}
                      className={`rounded-full border px-3 py-1.5 text-xs font-medium transition ${
                        isSelected
                          ? "border-[var(--accent-3)] bg-[var(--accent-3)] text-white"
                          : "border-[#d7d7d7] bg-white text-[#262626] hover:border-[var(--accent-3)] hover:bg-[#fff4f4]"
                      }`}
                    >
                      {theme}
                    </button>
                  );
                })}
              </div>
            )}
          </div>
        ) : null}

        {customThemeConfig.isEnabled ? (
          <div className="space-y-2 rounded-2xl border border-dashed border-[var(--accent-3)] bg-[#fff8f8] p-4">
            <p className="text-sm font-medium text-[var(--foreground)]">Thème sur mesure</p>
            <button
              type="button"
              onClick={() => {
                setUsesCustomTheme(true);
                setIsCustomThemeModalOpen(true);
                setSubmitError(null);
              }}
              className={`inline-flex rounded-xl border px-4 py-2 text-sm font-semibold transition ${
                usesCustomTheme
                  ? "border-[var(--accent-3)] bg-[var(--accent-3)] text-white"
                  : "border-[var(--accent-3)] bg-white text-[var(--accent-3)] hover:bg-[#fff1f1]"
              }`}
            >
              {usesCustomTheme ? "Modifier mon thème personnalisé" : customThemeConfig.optionLabel}
            </button>
            {customThemeConfig.helperText ? <p className="text-xs text-[var(--muted)]">{customThemeConfig.helperText}</p> : null}
            {usesCustomTheme && customThemeSummary.length > 0 ? (
              <div className="space-y-1 text-xs text-[var(--muted)]">
                {customThemeSummary.slice(0, 4).map((line) => (
                  <p key={line}>{line}</p>
                ))}
              </div>
            ) : null}
          </div>
        ) : null}

        {!supportsThemeChoice && !customThemeConfig.isEnabled ? (
          <div className="rounded-2xl border border-[var(--line)] bg-white p-4 text-sm text-[var(--muted)]">
            Aucun thème spécifique n&apos;est configuré pour ce produit. Vous pouvez l&apos;ajouter tel quel au panier.
          </div>
        ) : null}

        {selectedThemeValue ? (
          <div className="rounded-2xl border border-[var(--line)] bg-white p-4 text-sm">
            <span className="font-medium text-[var(--foreground)]">Sélection actuelle:</span>
            <span className="ml-2 text-[var(--muted)]">{selectedThemeValue}</span>
          </div>
        ) : null}

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

        {showSubmitButton ? (
          <button
            onClick={handleSubmit}
            disabled={isSubmitting}
            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..." : submitLabel}
          </button>
        ) : null}
      </div>

      {isCustomThemeModalOpen ? (
        <div
          className="fixed inset-0 z-[10000] bg-[rgba(24,18,18,0.6)] px-4 py-4"
          onClick={() => setIsCustomThemeModalOpen(false)}
        >
          <div className="flex min-h-full items-start justify-center md:items-center">
            <div
              className="max-h-[calc(100dvh-2rem)] w-full max-w-2xl overflow-y-auto rounded-[1.8rem] bg-white p-5 shadow-[0_24px_80px_rgba(24,18,18,0.28)] md:p-6"
              onClick={(event) => event.stopPropagation()}
            >
              <div className="flex items-start justify-between gap-4">
                <div className="space-y-2">
                  <p className="text-xs font-semibold uppercase tracking-[0.16em] text-[var(--accent-3)]">Thème sur mesure</p>
                  <h3 className="font-serif text-3xl text-[var(--foreground)]">{customThemeConfig.modalTitle}</h3>
                  <p className="text-sm text-[var(--muted)]">{customThemeConfig.modalDescription}</p>
                </div>
                <button
                  type="button"
                  onClick={() => setIsCustomThemeModalOpen(false)}
                  className="rounded-full border border-[var(--line)] px-3 py-1 text-sm font-medium text-[var(--foreground)]"
                >
                  Fermer
                </button>
              </div>

              <div className="mt-5 space-y-4">
                {DEFAULT_CUSTOM_THEME_FIELDS.map(renderCustomizationField)}
              </div>

              <div className="mt-6 flex flex-wrap items-center justify-between gap-3 rounded-[1.35rem] border border-[rgba(166,89,72,0.22)] bg-[rgba(252,248,246,0.98)] px-4 py-4">
                <button
                  type="button"
                  onClick={() => {
                    setUsesCustomTheme(false);
                    setIsCustomThemeModalOpen(false);
                  }}
                  className="rounded-xl border border-[var(--line)] px-4 py-2 text-sm font-semibold text-[var(--foreground)] hover:bg-[#faf6f6]"
                >
                  {supportsThemeChoice ? "Revenir aux thèmes existants" : "Annuler"}
                </button>
                <button
                  type="button"
                  onClick={() => {
                    setUsesCustomTheme(true);
                    setIsCustomThemeModalOpen(false);
                  }}
                  className="rounded-xl bg-[var(--accent-3)] px-4 py-2 text-sm font-semibold text-white hover:bg-[var(--accent-2)]"
                >
                  Enregistrer ma personnalisation
                </button>
              </div>
            </div>
          </div>
        </div>
      ) : null}
    </>
  );
}
