"use client";

import type { JSX } from "react";

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

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

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

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

    return (
      <InfoTemplate
        screen={infoScreen}
        onContinue={onContinue}
        canGoBack={canGoBack}
        onBack={onBack}
        screenProgress={screenProgress}
        defaultTexts={defaultTexts}
      />
    );
  },
  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;

    return (
      <ListTemplate
        screen={listScreen}
        selectedOptionIds={selectedOptionIds}
        onSelectionChange={onSelectionChange}
        actionButtonProps={hasActionButton
          ? {
              children: buttonText,
              disabled: actionDisabled,
              onClick: actionDisabled ? undefined : onContinue,
            }
          : undefined}
        canGoBack={canGoBack}
        onBack={onBack}
        screenProgress={screenProgress}
      />
    );
  },
  email: ({ screen, selectedOptionIds, onSelectionChange, onContinue, canGoBack, onBack, screenProgress, defaultTexts }) => {
    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}
      />
    );
  },
  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}
      />
    );
  },
};

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;
}
