"use client";

import type { JSX } from "react";

import {
  ListTemplate,
  InfoTemplate,
  DateTemplate,
  CouponTemplate,
  FormTemplate,
  EmailTemplate,
  LoadersTemplate,
  SoulmatePortraitTemplate,
  TrialPaymentTemplate,
  SpecialOfferTemplate,
  TrialChoiceTemplate,
} from "@/components/funnel/templates";
import type {
  ListScreenDefinition,
  DateScreenDefinition,
  FormScreenDefinition,
  CouponScreenDefinition,
  InfoScreenDefinition,
  EmailScreenDefinition,
  LoadersScreenDefinition,
  SoulmatePortraitScreenDefinition,
  TrialPaymentScreenDefinition,
  ScreenDefinition,
  DefaultTexts,
  FunnelDefinition,
  FunnelAnswers,
  SpecialOfferScreenDefinition,
  TrialChoiceScreenDefinition,
} from "@/lib/funnel/types";

export interface ScreenRenderProps {
  funnel: FunnelDefinition;
  screen: ScreenDefinition;
  selectedOptionIds: string[];
  onSelectionChange: (ids: string[], skipCheckChanges?: boolean) => void;
  onContinue: () => void;
  canGoBack: boolean;
  onBack: () => void;
  screenProgress: { current: number; total: number };
  defaultTexts?: DefaultTexts;
  answers: FunnelAnswers;
}

export type TemplateRenderer = (props: ScreenRenderProps) => JSX.Element;

const TEMPLATE_REGISTRY: Record<
  ScreenDefinition["template"],
  TemplateRenderer
> = {
  info: ({
    screen,
    onContinue,
    canGoBack,
    onBack,
    screenProgress,
    defaultTexts,
    answers,
  }) => {
    const infoScreen = screen as InfoScreenDefinition;

    return (
      <InfoTemplate
        screen={infoScreen}
        onContinue={onContinue}
        canGoBack={canGoBack}
        onBack={onBack}
        screenProgress={screenProgress}
        defaultTexts={defaultTexts}
        answers={answers}
      />
    );
  },
  date: ({
    screen,
    selectedOptionIds,
    onSelectionChange,
    onContinue,
    canGoBack,
    onBack,
    screenProgress,
    defaultTexts,
  }) => {
    const dateScreen = screen as DateScreenDefinition;

    // For date screens, we store date components as array: [month, day, year]
    const currentDateArray = selectedOptionIds;
    const selectedDate = {
      month: currentDateArray[0] || "",
      day: currentDateArray[1] || "",
      year: currentDateArray[2] || "",
    };

    const handleDateChange = (date: {
      month?: string;
      day?: string;
      year?: string;
    }) => {
      const dateArray = [date.month || "", date.day || "", date.year || ""];
      onSelectionChange(dateArray);
    };

    return (
      <DateTemplate
        screen={dateScreen}
        selectedDate={selectedDate}
        onDateChange={handleDateChange}
        onContinue={onContinue}
        canGoBack={canGoBack}
        onBack={onBack}
        screenProgress={screenProgress}
        defaultTexts={defaultTexts}
      />
    );
  },
  form: ({
    screen,
    selectedOptionIds,
    onSelectionChange,
    onContinue,
    canGoBack,
    onBack,
    screenProgress,
    defaultTexts,
  }) => {
    const formScreen = screen as FormScreenDefinition;

    // For form screens, we store form data as JSON string in the first element
    const formDataJson = selectedOptionIds[0] || "{}";
    let formData: Record<string, string> = {};

    try {
      formData = JSON.parse(formDataJson);
    } catch {
      formData = {};
    }

    const handleFormDataChange = (data: Record<string, string>) => {
      const dataJson = JSON.stringify(data);
      onSelectionChange([dataJson]);
    };

    return (
      <FormTemplate
        screen={formScreen}
        formData={formData}
        onFormDataChange={handleFormDataChange}
        onContinue={onContinue}
        canGoBack={canGoBack}
        onBack={onBack}
        screenProgress={screenProgress}
        defaultTexts={defaultTexts}
      />
    );
  },
  coupon: ({
    screen,
    onContinue,
    canGoBack,
    onBack,
    screenProgress,
    defaultTexts,
  }) => {
    const couponScreen = screen as CouponScreenDefinition;

    return (
      <CouponTemplate
        screen={couponScreen}
        onContinue={onContinue}
        canGoBack={canGoBack}
        onBack={onBack}
        screenProgress={screenProgress}
        defaultTexts={defaultTexts}
      />
    );
  },
  list: ({
    screen,
    selectedOptionIds,
    onSelectionChange,
    onContinue,
    canGoBack,
    onBack,
    screenProgress,
    defaultTexts,
  }) => {
    const listScreen = screen as ListScreenDefinition;
    const isSelectionEmpty = selectedOptionIds.length === 0;

    // Используем только общую кнопку экрана
    const bottomActionButton = listScreen.bottomActionButton;
    const isButtonDisabled = bottomActionButton?.show === false;

    // Простая логика: кнопка есть если не отключена (show: false)
    const hasActionButton = !isButtonDisabled;

    // Правильная логика приоритетов для текста кнопки:
    // 1. bottomActionButton.text (настройка экрана)
    // 2. defaultTexts.nextButton (глобальная настройка воронки)
    // 3. "Next" (хардкод fallback)
    const buttonText =
      bottomActionButton?.text || defaultTexts?.nextButton || "Next";

    const actionDisabled = hasActionButton && isSelectionEmpty;

    // Для LIST экранов всегда показываем blur (даже без кнопки)
    const showGradientBlur = bottomActionButton?.showGradientBlur ?? true;

    return (
      <ListTemplate
        screen={listScreen}
        selectedOptionIds={selectedOptionIds}
        onSelectionChange={onSelectionChange}
        actionButtonProps={
          hasActionButton
            ? {
                children: buttonText,
                disabled: actionDisabled,
                onClick: actionDisabled ? undefined : onContinue,
              }
            : undefined
        }
        showGradientBlur={showGradientBlur}
        canGoBack={canGoBack}
        onBack={onBack}
        screenProgress={screenProgress}
      />
    );
  },
  email: ({
    screen,
    selectedOptionIds,
    onSelectionChange,
    onContinue,
    canGoBack,
    onBack,
    screenProgress,
    defaultTexts,
    funnel,
    answers,
  }) => {
    const emailScreen = screen as EmailScreenDefinition;

    // For email screens, we store email as single string in first element
    const selectedEmail = selectedOptionIds[0] || "";

    const handleEmailChange = (email: string) => {
      onSelectionChange([email]);
    };

    return (
      <EmailTemplate
        screen={emailScreen}
        selectedEmail={selectedEmail}
        onEmailChange={handleEmailChange}
        onContinue={onContinue}
        canGoBack={canGoBack}
        onBack={onBack}
        screenProgress={screenProgress}
        defaultTexts={defaultTexts}
        funnel={funnel}
        answers={answers}
      />
    );
  },
  loaders: ({
    screen,
    onContinue,
    canGoBack,
    onBack,
    screenProgress,
    defaultTexts,
  }) => {
    const loadersScreen = screen as LoadersScreenDefinition;

    return (
      <LoadersTemplate
        screen={loadersScreen}
        onContinue={onContinue}
        canGoBack={canGoBack}
        onBack={onBack}
        screenProgress={screenProgress}
        defaultTexts={defaultTexts}
      />
    );
  },
  soulmate: ({
    screen,
    onContinue,
    canGoBack,
    onBack,
    screenProgress,
    defaultTexts,
  }) => {
    const soulmateScreen = screen as SoulmatePortraitScreenDefinition;

    return (
      <SoulmatePortraitTemplate
        screen={soulmateScreen}
        onContinue={onContinue}
        canGoBack={canGoBack}
        onBack={onBack}
        screenProgress={screenProgress}
        defaultTexts={defaultTexts}
      />
    );
  },
  trialPayment: ({
    screen,
    onContinue,
    canGoBack,
    onBack,
    screenProgress,
    defaultTexts,
    funnel,
  }) => {
    const trialPaymentScreen = screen as TrialPaymentScreenDefinition;

    return (
      <TrialPaymentTemplate
        screen={trialPaymentScreen}
        onContinue={onContinue}
        canGoBack={canGoBack}
        onBack={onBack}
        screenProgress={screenProgress}
        defaultTexts={defaultTexts}
        funnel={funnel}
      />
    );
  },
  specialOffer: ({
    screen,
    onContinue,
    canGoBack,
    onBack,
    screenProgress,
    defaultTexts,
    funnel,
  }) => {
    const specialOfferScreen = screen as SpecialOfferScreenDefinition;

    return (
      <SpecialOfferTemplate
        funnel={funnel}
        screen={specialOfferScreen}
        onContinue={onContinue}
        canGoBack={canGoBack}
        onBack={onBack}
        screenProgress={screenProgress}
        defaultTexts={defaultTexts}
      />
    );
  },
  trialChoice: ({
    funnel,
    screen,
    onContinue,
    canGoBack,
    onBack,
    screenProgress,
    defaultTexts,
    answers,
  }) => {
    const trialChoiceScreen = screen as TrialChoiceScreenDefinition;

    return (
      <TrialChoiceTemplate
        funnel={funnel}
        screen={trialChoiceScreen}
        onContinue={onContinue}
        canGoBack={canGoBack}
        onBack={onBack}
        screenProgress={screenProgress}
        defaultTexts={defaultTexts}
        answers={answers}
      />
    );
  },
};

export function renderScreen(props: ScreenRenderProps): JSX.Element {
  const renderer = TEMPLATE_REGISTRY[props.screen.template];
  if (!renderer) {
    throw new Error(`Unsupported template: ${props.screen.template}`);
  }
  return renderer(props);
}

export function getTemplateRenderer(
  screen: ScreenDefinition
): TemplateRenderer {
  const renderer = TEMPLATE_REGISTRY[screen.template];
  if (!renderer) {
    throw new Error(`Unsupported template: ${screen.template}`);
  }
  return renderer;
}
