export type TypographyVariant = {
  text?: string; // Опционально для случаев { show: false }
  font?: "manrope" | "inter" | "geistSans" | "geistMono";
  weight?: "regular" | "medium" | "semiBold" | "bold" | "extraBold" | "black";
  size?: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl";
  align?: "center" | "left" | "right";
  color?:
    | "default"
    | "primary"
    | "secondary"
    | "destructive"
    | "success"
    | "card"
    | "accent"
    | "muted";
  className?: string;
};

// Extended typography for titles/subtitles with show property
export interface TitleDefinition extends TypographyVariant {
  show?: boolean; // Controls whether title should be displayed. Defaults to true.
}

export interface SubtitleDefinition extends TypographyVariant {
  show?: boolean; // Controls whether subtitle should be displayed. Defaults to true.
}

export interface HeaderProgressDefinition {
  /** When both current and total provided, value is computed automatically (current / total * 100). */
  current?: number;
  total?: number;
  /** Explicit percentage override (0-100). */
  value?: number;
  label?: string;
  className?: string;
}

export interface HeaderDefinition {
  progress?: HeaderProgressDefinition;
  /** Controls whether back button should be displayed. Defaults to true. */
  showBackButton?: boolean;
  /** Controls whether progress bar and label should be displayed. Defaults to true. */
  showProgress?: boolean;
  /** Controls whether header should be displayed at all. Defaults to true. */
  show?: boolean;
}

export type SelectionType = "single" | "multi";

export interface ListOptionDefinition {
  id: string;
  label: string;
  description?: string;
  emoji?: string;
  /** Optional machine-readable value; defaults to the option id. */
  value?: string;
  disabled?: boolean;
}

export interface BottomActionButtonDefinition {
  /** Controls whether button should be displayed. Defaults to true. */
  show?: boolean;
  text?: string;
  cornerRadius?: "3xl" | "full";
  /** Controls whether PrivacyTermsConsent should be shown under the button. Defaults to false. */
  showPrivacyTermsConsent?: boolean;
  /** Controls whether gradient blur should be shown. Defaults to true. */
  showGradientBlur?: boolean;
}

export interface DefaultTexts {
  nextButton?: string; // "Next"
  continueButton?: string; // "Continue"
  privacyBanner?: string; // "Мы не передаем личную информацию..."
}

export interface NavigationConditionDefinition {
  screenId: string;
  /**
   * Тип условия:
   * - options: проверка выбранных опций в списках
   * - values: проверка конкретных значений (зодиак, email, дата, etc.)
   * - unleash: проверка AB тестов через Unleash feature flags
   */
  conditionType?: "options" | "values" | "unleash";
  /**
   * - includesAny: at least one option/value is present.
   * - includesAll: all of the options/values are present.
   * - includesExactly: only the specified options/values are present.
   * - equals: точное совпадение значения (для одиночных значений)
   */
  operator?: "includesAny" | "includesAll" | "includesExactly" | "equals";

  // Для list экранов (legacy, но поддерживается)
  optionIds?: string[];

  // Для любых экранов - универсальные значения
  values?: string[];

  // Для Unleash AB тестов
  /**
   * Название Unleash feature flag (например, "trial-button-test")
   * Используется только когда conditionType === "unleash"
   */
  unleashFlag?: string;
  /**
   * Ожидаемые варианты флага (например, ["v1", "v2"])
   * Проверяется с помощью operator (includesAny, includesAll, equals)
   * Используется только когда conditionType === "unleash"
   */
  unleashVariants?: string[];
}

export interface NavigationRuleDefinition {
  conditions: NavigationConditionDefinition[];
  nextScreenId: string;
}

export interface NavigationDefinition {
  defaultNextScreenId?: string;
  rules?: NavigationRuleDefinition[];
  isEndScreen?: boolean; //  Указывает что это финальный экран воронки
  /** Экран, на который нужно перейти при попытке возврата назад (UI/браузер) */
  onBackScreenId?: string;
}

// Рекурсивный Partial для глубоких вложенных объектов
// Поддерживает null для явного удаления полей в вариантах экранов
type DeepPartial<T> = T extends object
  ? {
      [P in keyof T]?: DeepPartial<T[P]> | null;
    }
  : T | null;

// Варианты могут переопределять любые поля экрана, включая вложенные объекты
type ScreenVariantOverrides<T> = DeepPartial<
  Omit<T, "id" | "template" | "variants">
>;

export interface ScreenVariantDefinition<
  T extends { id: string; template: string }
> {
  conditions: NavigationConditionDefinition[];
  overrides: ScreenVariantOverrides<T>;
}

export interface IconDefinition {
  type?: "emoji" | "image"; // Опционально для вариантов - наследуется от основного экрана
  value: string;
  size?: "sm" | "md" | "lg" | "xl";
  className?: string;
}

/**
 * Одно правило подстановки значения переменной на основе условий.
 */
export interface VariableMapping {
  /** Условия при которых применяется это значение */
  conditions: NavigationConditionDefinition[];
  /** Значение которое будет подставлено если условия выполнены */
  value: string;
}

/**
 * Определение переменной для динамической подстановки в текст.
 * Синтаксис использования: {{variableName}}
 *
 * Пример:
 * - name: "gender"
 * - mappings: [
 *     { conditions: [{ screenId: "gender", values: ["female"] }], value: "женщин" },
 *     { conditions: [{ screenId: "gender", values: ["male"] }], value: "мужчин" }
 *   ]
 * - fallback: "людей"
 */
export interface VariableDefinition {
  /** Имя переменной (используется в тексте как {{name}}) */
  name: string;
  /** Массив правил подстановки (проверяются по порядку) */
  mappings: VariableMapping[];
  /** Значение по умолчанию если ни одно условие не сработало */
  fallback?: string;
}

export interface InfoScreenDefinition {
  id: string;
  template: "info";
  header?: HeaderDefinition;
  title: TitleDefinition;
  subtitle?: SubtitleDefinition;
  icon?: IconDefinition;
  /** Переменные для динамической подстановки в текст */
  variables?: VariableDefinition[];
  bottomActionButton?: BottomActionButtonDefinition;
  navigation?: NavigationDefinition;
  variants?: ScreenVariantDefinition<InfoScreenDefinition>[];
}

export interface DateInputDefinition {
  monthPlaceholder?: string;
  dayPlaceholder?: string;
  yearPlaceholder?: string;
  monthLabel?: string;
  dayLabel?: string;
  yearLabel?: string;
  showSelectedDate?: boolean;
  selectedDateFormat?: string; // e.g., "MMMM d, yyyy" for "April 8, 1987"
  validationMessage?: string;
  selectedDateLabel?: string; // "Выбранная дата:" text
  zodiac?: {
    enabled?: boolean;
    storageKey?: string;
  };
  /**
   * Ключ поля для регистрации пользователя и сессии.
   * Поддерживает многоуровневую вложенность через точку.
   * Дата передается в формате: "YYYY-MM-DD HH:mm" (время всегда 12:00)
   * Например: "profile.birthdate" → { profile: { birthdate: "2000-07-03 12:00" } }
   */
  registrationFieldKey?: string;
}

export interface DateScreenDefinition {
  id: string;
  template: "date";
  header?: HeaderDefinition;
  title: TitleDefinition;
  subtitle?: SubtitleDefinition;
  dateInput: DateInputDefinition;
  bottomActionButton?: BottomActionButtonDefinition;
  navigation?: NavigationDefinition;
  variants?: ScreenVariantDefinition<DateScreenDefinition>[];
}

export interface CouponDefinition {
  title: TypographyVariant;
  offer: {
    title: TypographyVariant;
    description: TypographyVariant;
  };
  promoCode: TypographyVariant;
  footer: TypographyVariant;
}

export interface CouponScreenDefinition {
  id: string;
  template: "coupon";
  header?: HeaderDefinition;
  title: TitleDefinition;
  subtitle?: SubtitleDefinition;
  coupon: CouponDefinition;
  copiedMessage?: string;
  bottomActionButton?: BottomActionButtonDefinition;
  navigation?: NavigationDefinition;
  variants?: ScreenVariantDefinition<CouponScreenDefinition>[];
}

export interface FormFieldDefinition {
  id: string;
  label?: string;
  placeholder?: string;
  type?: "text" | "email" | "tel";
  required?: boolean;
  validation?: {
    message?: string;
  };
}

export interface FormValidationMessages {
  required?: string; // "${field} is required"
}

export interface FormScreenDefinition {
  id: string;
  template: "form";
  header?: HeaderDefinition;
  title: TitleDefinition;
  subtitle?: SubtitleDefinition;
  fields: FormFieldDefinition[];
  validationMessages?: FormValidationMessages;
  bottomActionButton?: BottomActionButtonDefinition;
  navigation?: NavigationDefinition;
  variants?: ScreenVariantDefinition<FormScreenDefinition>[];
}

export interface ListScreenDefinition {
  id: string;
  template: "list";
  header?: HeaderDefinition;
  title: TitleDefinition;
  subtitle?: SubtitleDefinition;
  list: {
    selectionType: SelectionType;
    options: ListOptionDefinition[];
    /**
     * Ключ поля для регистрации пользователя (только для single selection).
     * Поддерживает многоуровневую вложенность через точку.
     * Например: "profile.gender" → { profile: { gender: "selected-id" } }
     */
    registrationFieldKey?: string;
  };
  bottomActionButton?: BottomActionButtonDefinition;
  navigation?: NavigationDefinition;
  variants?: ScreenVariantDefinition<ListScreenDefinition>[];
}

export interface ImageDefinition {
  src: string;
}

export interface EmailInputDefinition {
  placeholder?: string;
  label?: string;
}

// Email Screen Definition
export interface EmailScreenDefinition {
  id: string;
  template: "email";
  header?: HeaderDefinition;
  title: TitleDefinition;
  subtitle?: SubtitleDefinition;
  emailInput: EmailInputDefinition;
  image?: ImageDefinition;
  bottomActionButton?: BottomActionButtonDefinition;
  navigation?: NavigationDefinition;
  variants?: ScreenVariantDefinition<EmailScreenDefinition>[];
}

export interface ProgressbarDefinition {
  items: Array<{
    title?: string;
    subtitle?: string;
    processingTitle?: string;
    processingSubtitle?: string;
    completedTitle?: string;
    completedSubtitle?: string;
  }>;
  transitionDuration?: number;
}

export interface LoadersScreenDefinition {
  id: string;
  template: "loaders";
  header?: HeaderDefinition;
  title: TitleDefinition;
  subtitle?: SubtitleDefinition;
  progressbars: ProgressbarDefinition;
  bottomActionButton?: BottomActionButtonDefinition;
  navigation?: NavigationDefinition;
  variants?: ScreenVariantDefinition<LoadersScreenDefinition>[];
}

// SoulmatePortrait Screen Definition
export interface SoulmatePortraitScreenDefinition {
  id: string;
  template: "soulmate";
  header?: HeaderDefinition;
  title: TitleDefinition;
  subtitle?: SubtitleDefinition;
  description?: TypographyVariant; // Настраиваемый текст описания
  soulmatePortraitsDelivered?: {
    image?: string; // Legacy support - используется как background если нет mediaUrl
    mediaType?: "image" | "video" | "gif"; // Тип медиа контента
    mediaUrl?: string; // URL видео/gif файла (приоритет над image)
    text?: TypographyVariant;
    avatars?: Array<{
      src: string;
      alt?: string;
      fallbackText?: string;
    }>;
  };
  textList?: {
    items: TypographyVariant[];
  };
  bottomActionButton?: BottomActionButtonDefinition;
  navigation?: NavigationDefinition;
  variants?: ScreenVariantDefinition<SoulmatePortraitScreenDefinition>[];
}

// TrialPayment Screen Definition (лендинг оплаты с большим количеством секций)
export interface TrialPaymentScreenDefinition {
  id: string;
  template: "trialPayment";
  header?: HeaderDefinition;
  // В TrialPayment заголовок и подзаголовок используются опционально сверху экрана
  title?: TitleDefinition;
  subtitle?: SubtitleDefinition;
  // Глобальная нижняя кнопка экрана
  bottomActionButton?: BottomActionButtonDefinition;
  navigation?: NavigationDefinition;
  variants?: ScreenVariantDefinition<TrialPaymentScreenDefinition>[];
  // Минимальные секции для первого шага миграции
  headerBlock?: {
    text?: TypographyVariant;
    timer?: TypographyVariant;
    timerSeconds?: number;
  };
  unlockYourSketch?: {
    title?: TypographyVariant;
    subtitle?: TypographyVariant;
    image?: ImageDefinition;
    blur?: {
      text?: TypographyVariant;
      icon?: "lock";
    };
    buttonText?: string;
  };
  joinedToday?: {
    count?: TypographyVariant;
    text?: TypographyVariant;
  };
  trustedByOver?: {
    text?: TypographyVariant;
  };
  findingOneGuide?: {
    header?: {
      emoji?: TypographyVariant;
      title?: TypographyVariant;
    };
    text?: TypographyVariant;
    blur?: {
      text?: TypographyVariant;
      icon?: "lock";
    };
  };
  tryForDays?: {
    title?: TypographyVariant;
    textList?: {
      items: TypographyVariant[];
    };
  };
  totalPrice?: {
    couponContainer: {
      title?: TypographyVariant;
      buttonText?: string;
    };
    priceContainer?: {
      title?: TypographyVariant;
      price?: TypographyVariant;
      oldPrice?: TypographyVariant;
      discount?: TypographyVariant;
    };
  };
  paymentButtons?: {
    buttons: Array<{
      text: string;
      icon?: "pay" | "google" | "card";
      primary?: boolean;
    }>;
  };
  moneyBackGuarantee?: {
    title?: TypographyVariant;
    text?: TypographyVariant;
  };
  policy?: {
    text?: TypographyVariant;
  };
  usersPortraits?: {
    title?: TypographyVariant;
    images?: ImageDefinition[];
    buttonText?: string;
  };
  joinedTodayWithAvatars?: {
    count?: TypographyVariant;
    text?: TypographyVariant;
    avatars?: {
      // minimal: только пути
      images: ImageDefinition[];
    };
  };
  progressToSeeSoulmate?: {
    title?: TypographyVariant;
    progress?: {
      value: number;
    };
    leftText?: TypographyVariant;
    rightText?: TypographyVariant;
  };
  stepsToSeeSoulmate?: {
    steps: Array<{
      title: TypographyVariant;
      description: TypographyVariant;
      icon?: "questions" | "profile" | "sketch" | "astro" | "chat";
      isActive?: boolean;
    }>;
    buttonText?: string;
  };
  reviews?: {
    title?: TypographyVariant;
    items: Array<{
      // минимальный набор, дальше расширим
      name: TypographyVariant;
      text: TypographyVariant;
      avatar?: ImageDefinition;
      rating?: number;
      date?: TypographyVariant;
      portrait?: ImageDefinition;
      photo?: ImageDefinition;
    }>;
  };
  commonQuestions?: {
    title?: TypographyVariant;
    items: Array<{
      question: string;
      answer: string;
    }>;
  };
  stillHaveQuestions?: {
    title?: TypographyVariant;
    actionButtonText?: string;
    contactButtonText?: string;
  };
  footer?: {
    title?: TypographyVariant;
    contacts?: {
      title?: TypographyVariant;
      email?: { href: string; text: string };
      address?: TypographyVariant;
    };
    legal?: {
      title?: TypographyVariant;
      links?: Array<{ href: string; text: string }>;
      copyright?: TypographyVariant;
    };
    paymentMethods?: {
      title?: TypographyVariant;
      methods?: Array<{ src: string; alt: string }>;
    };
  };
}

export interface SpecialOfferScreenDefinition {
  id: string;
  template: "specialOffer";
  header?: HeaderDefinition;
  title?: TitleDefinition;
  subtitle?: SubtitleDefinition;
  // coupon: CouponDefinition;
  text: {
    title?: TypographyVariant;
    subtitle?: TypographyVariant;
    description?: {
      trialPrice?: TypographyVariant;
      text?: TypographyVariant;
      oldTrialPrice?: TypographyVariant;
    };
  };
  advantages?: {
    items: Array<{
      icon?: TypographyVariant;
      text?: TypographyVariant;
    }>;
  };
  bottomActionButton?: BottomActionButtonDefinition;
  navigation?: NavigationDefinition;
  variants?: ScreenVariantDefinition<SpecialOfferScreenDefinition>[];
}

export interface TrialChoiceScreenDefinition {
  id: string;
  template: "trialChoice";
  header?: HeaderDefinition;
  title: TitleDefinition;
  subtitle?: SubtitleDefinition;
  bottomActionButton?: BottomActionButtonDefinition;
  navigation?: NavigationDefinition;
  variants?: ScreenVariantDefinition<TrialChoiceScreenDefinition>[];
}

export type ScreenDefinition =
  | InfoScreenDefinition
  | DateScreenDefinition
  | CouponScreenDefinition
  | FormScreenDefinition
  | ListScreenDefinition
  | EmailScreenDefinition
  | LoadersScreenDefinition
  | SoulmatePortraitScreenDefinition
  | TrialPaymentScreenDefinition
  | SpecialOfferScreenDefinition
  | TrialChoiceScreenDefinition;

export interface FunnelMetaDefinition {
  id: string;
  version?: string;
  title?: string;
  description?: string;
  firstScreenId?: string;
  /**
   * Google Analytics Measurement ID (e.g., "G-XXXXXXXXXX")
   * If provided, Google Analytics will be loaded for this funnel
   */
  googleAnalyticsId?: string;
  /**
   * Yandex Metrika Counter ID (e.g., "95799066")
   * If provided, Yandex Metrika will be loaded for this funnel
   */
  yandexMetrikaId?: string;
}

export interface FunnelDefinition {
  meta: FunnelMetaDefinition;
  defaultTexts?: DefaultTexts;
  screens: ScreenDefinition[];
}

export type FunnelAnswers = Record<string, string[]>;
