"use client";

import { useCallback, useEffect, useMemo, useState } from "react";

import {
  useBuilderSelectedScreen,
  useBuilderState,
} from "@/lib/admin/builder/context";
import { renderScreen } from "@/lib/funnel/screenRenderer";
import { mergeScreenWithOverrides } from "@/lib/admin/builder/variants";
import { PreviewErrorBoundary } from "@/components/admin/ErrorBoundary";
import { PREVIEW_DIMENSIONS } from "@/lib/constants";
import {
  PaymentPlacementProvider,
  TrialVariantSelectionProvider,
} from "@/entities/session/payment";

// ✅ Мемоизированные моки - создаются один раз
const MOCK_CALLBACKS = {
  onContinue: () => {},
  onBack: () => {},
};

const MOCK_PROGRESS = { current: 1, total: 10 };

export function BuilderPreview() {
  const selectedScreen = useBuilderSelectedScreen();
  const builderState = useBuilderState();
  const [selectedIds, setSelectedIds] = useState<string[]>([]);
  const [previewVariantIndex, setPreviewVariantIndex] = useState<number | null>(
    null
  );

  useEffect(() => {
    if (!selectedScreen) {
      setSelectedIds([]);
      setPreviewVariantIndex(null);
      return;
    }

    setSelectedIds((prev) => {
      if (prev.length === 0) {
        return prev;
      }
      return [];
    });
  }, [selectedScreen]);

  const handleSelectionChange = useCallback((ids: string[]) => {
    setSelectedIds((prev) => {
      if (
        prev.length === ids.length &&
        prev.every((value, index) => value === ids[index])
      ) {
        return prev;
      }
      return ids;
    });
  }, []);

  const variants = useMemo(
    () => selectedScreen?.variants ?? [],
    [selectedScreen]
  );

  useEffect(() => {
    setPreviewVariantIndex(null);
  }, [selectedScreen]);

  const previewScreen = useMemo(() => {
    if (!selectedScreen) {
      return null;
    }

    if (previewVariantIndex === null) {
      return selectedScreen;
    }

    const variant = variants[previewVariantIndex];
    if (!variant) {
      return selectedScreen;
    }

    return mergeScreenWithOverrides(selectedScreen, variant.overrides ?? {});
  }, [previewVariantIndex, selectedScreen, variants]);

  const renderScreenPreview = useCallback(() => {
    if (!previewScreen) return null;

    try {
      // ✅ Собираем объект funnel из builderState для передачи в renderScreen
      const mockFunnel = {
        meta: builderState.meta,
        defaultTexts: builderState.defaultTexts,
        screens: builderState.screens,
      };

      return renderScreen({
        funnel: mockFunnel,
        screen: previewScreen,
        selectedOptionIds: selectedIds,
        onSelectionChange: handleSelectionChange,
        onContinue: MOCK_CALLBACKS.onContinue,
        canGoBack: true,
        onBack: MOCK_CALLBACKS.onBack,
        screenProgress: MOCK_PROGRESS,
        defaultTexts: builderState.defaultTexts,
        answers: {}, // Mock empty answers для превью
      });
    } catch (error) {
      console.error("Error rendering preview:", error);
      return (
        <div className="flex h-32 items-center justify-center rounded-lg border border-dashed border-border text-sm text-muted-foreground">
          Ошибка при отображении превью:{" "}
          {error instanceof Error ? error.message : "Неизвестная ошибка"}
        </div>
      );
    }
  }, [
    previewScreen,
    selectedIds,
    handleSelectionChange,
    builderState.meta,
    builderState.defaultTexts,
    builderState.screens,
  ]);

  const preview = useMemo(() => {
    if (!previewScreen) {
      return (
        <div
          className="flex items-center justify-center mx-auto"
          style={{
            height: `${PREVIEW_DIMENSIONS.EMPTY_HEIGHT}px`,
            width: `${PREVIEW_DIMENSIONS.WIDTH}px`,
          }}
        >
          <div className="flex items-center justify-center rounded-lg border border-dashed border-border bg-muted/30 text-sm text-muted-foreground w-full h-full">
            Выберите экран для предпросмотра
          </div>
        </div>
      );
    }

    // ✅ Используем константы для размеров preview
    const PREVIEW_WIDTH = PREVIEW_DIMENSIONS.WIDTH;
    const PREVIEW_HEIGHT = PREVIEW_DIMENSIONS.HEIGHT;

    return (
      <div className="mx-auto space-y-3" style={{ width: PREVIEW_WIDTH }}>
        {variants.length > 0 && (
          <div className="rounded-lg border border-border/60 bg-background/90 p-2 text-xs text-muted-foreground">
            <div className="flex items-center justify-between gap-2">
              <span className="font-semibold uppercase tracking-wide text-muted-foreground/80">
                Превью варианта
              </span>
              <select
                className="rounded-md border border-border bg-background px-2 py-1 text-xs"
                value={
                  previewVariantIndex === null
                    ? "base"
                    : String(previewVariantIndex)
                }
                onChange={(event) =>
                  setPreviewVariantIndex(
                    event.target.value === "base"
                      ? null
                      : Number(event.target.value)
                  )
                }
              >
                <option value="base">Основной экран</option>
                {variants.map((variant, index) => (
                  <option key={index} value={index}>
                    Вариант {index + 1}
                  </option>
                ))}
              </select>
            </div>
            {previewVariantIndex !== null && (
              <div className="mt-2 rounded border border-blue-200 bg-blue-50 px-2 py-1 text-[11px] text-blue-700 dark:border-blue-800 dark:bg-blue-900/20 dark:text-blue-200">
                ⚠️ Превью принудительно показывает вариант. В реальной воронке
                он показывается только при выполнении условий.
              </div>
            )}
          </div>
        )}

        {/* Mobile Frame - Simple Border */}
        <div
          className="relative bg-white rounded-2xl border-4 border-gray-300 shadow-lg mx-auto"
          style={{
            height: PREVIEW_HEIGHT,
            width: PREVIEW_WIDTH,
            overflow: "hidden", // Hide anything that goes outside
            contain: "layout style paint", // CSS containment
            isolation: "isolate", // Create new stacking context
            transform: "translateZ(0)", // Force new layer
          }}
        >
          {/* Screen Content with scroll - wrapped in Error Boundary */}
          <PreviewErrorBoundary>
            <PaymentPlacementProvider>
              <TrialVariantSelectionProvider>
                <div className="w-full h-full overflow-y-auto overflow-x-hidden [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]">
                  {renderScreenPreview()}
                </div>
              </TrialVariantSelectionProvider>
            </PaymentPlacementProvider>
          </PreviewErrorBoundary>
        </div>
      </div>
    );
  }, [previewScreen, renderScreenPreview, variants, previewVariantIndex]);

  return preview;
}
