import { FunnelAnswers, NavigationConditionDefinition, NavigationRuleDefinition, ScreenDefinition } from "./types";
import { calculateAgeFromArray, createAgeValue, createGenerationValue } from "@/lib/age-utils";
import { getZodiacSign } from "@/lib/funnel/zodiac";

/**
 * Тип для функции проверки Unleash условий
 * Передается извне чтобы избежать зависимости от React hooks
 */
export type UnleashChecker = (
  flag: string,
  expectedVariants: string[],
  operator?: "includesAny" | "includesAll" | "includesExactly" | "equals"
) => boolean;

/**
 * Расширенная функция получения ответов экрана
 * Автоматически рассчитывает возраст и знак зодиака для date экранов
 */
function getScreenAnswers(answers: FunnelAnswers, screenId: string, allScreens?: ScreenDefinition[]): string[] {
  const rawAnswers = answers[screenId] ?? [];
  
  // 🎯 ОСОБАЯ ЛОГИКА для date экранов - автоматически добавляем рассчитанные значения
  const screen = allScreens?.find(s => s.id === screenId);
  if (screen?.template === "date" && rawAnswers.length === 3) {
    const [month, day, year] = rawAnswers.map(Number);
    
    // Валидируем дату
    if (month >= 1 && month <= 12 && day >= 1 && day <= 31 && year >= 1900) {
      const dateArray = [month, day, year];
      const enhancedAnswers = [...rawAnswers];
      
      try {
        // 🎂 Добавляем возрастные значения
        const age = calculateAgeFromArray(dateArray);
        if (age > 0) {
          enhancedAnswers.push(
            createAgeValue(age),                    // "26-30"
            `age-${age}`,                          // "age-25"  
            createGenerationValue(year)            // "millennials"
          );
        }
        
        // ♈ Добавляем знак зодиака
        const zodiac = getZodiacSign(month, day);
        if (zodiac) {
          enhancedAnswers.push(zodiac);         // "aries"
        }
      } catch (error) {
        // В случае ошибки возвращаем исходные ответы
        console.warn('Error calculating age/zodiac from date:', error);
      }
      
      return enhancedAnswers;
    }
  }
  
  return rawAnswers;
}

function satisfiesCondition(
  condition: NavigationConditionDefinition,
  answers: FunnelAnswers,
  allScreens?: ScreenDefinition[],
  unleashChecker?: UnleashChecker
): boolean {
  const conditionType = condition.conditionType ?? "options";

  // 🎯 UNLEASH AB ТЕСТЫ: проверка через Unleash feature flags
  if (conditionType === "unleash") {
    if (!unleashChecker || !condition.unleashFlag || !condition.unleashVariants) {
      return false;
    }
    
    const operator = condition.operator ?? "includesAny";
    return unleashChecker(
      condition.unleashFlag,
      condition.unleashVariants,
      operator
    );
  }

  // Существующая логика для options и values
  const selected = new Set(getScreenAnswers(answers, condition.screenId, allScreens));
  const operator = condition.operator ?? "includesAny";

  // 🎯 НОВАЯ ЛОГИКА: поддержка values для любых экранов
  const expectedValues = conditionType === "values" 
    ? new Set(condition.values ?? [])
    : new Set(condition.optionIds ?? []);

  if (expectedValues.size === 0) {
    return false;
  }

  switch (operator) {
    case "includesAny": {
      return Array.from(expectedValues).some((value) => selected.has(value));
    }
    case "includesAll": {
      return Array.from(expectedValues).every((value) => selected.has(value));
    }
    case "includesExactly": {
      if (selected.size !== expectedValues.size) {
        return false;
      }

      for (const value of expectedValues) {
        if (!selected.has(value)) {
          return false;
        }
      }

      return true;
    }
    case "equals": {
      // 🎯 НОВЫЙ ОПЕРАТОР: точное совпадение для одиночных значений
      const selectedArray = Array.from(selected);
      const expectedArray = Array.from(expectedValues);
      
      return selectedArray.length === 1 && 
             expectedArray.length === 1 && 
             selectedArray[0] === expectedArray[0];
    }
    default:
      return false;
  }
}

export function matchesNavigationConditions(
  conditions: NavigationConditionDefinition[] | undefined,
  answers: FunnelAnswers,
  allScreens?: ScreenDefinition[],
  unleashChecker?: UnleashChecker
): boolean {
  if (!conditions || conditions.length === 0) {
    return false;
  }

  return conditions.every((condition) => satisfiesCondition(condition, answers, allScreens, unleashChecker));
}

function satisfiesRule(
  rule: NavigationRuleDefinition, 
  answers: FunnelAnswers, 
  allScreens?: ScreenDefinition[],
  unleashChecker?: UnleashChecker
): boolean {
  return matchesNavigationConditions(rule.conditions, answers, allScreens, unleashChecker);
}

export function resolveNextScreenId(
  currentScreen: ScreenDefinition,
  answers: FunnelAnswers,
  orderedScreens: ScreenDefinition[],
  unleashChecker?: UnleashChecker
): string | undefined {
  const navigation = currentScreen.navigation;

  if (navigation?.rules) {
    for (const rule of navigation.rules) {
      if (satisfiesRule(rule, answers, orderedScreens, unleashChecker)) {
        return rule.nextScreenId;
      }
    }
  }

  if (navigation?.defaultNextScreenId) {
    return navigation.defaultNextScreenId;
  }

  const currentIndex = orderedScreens.findIndex((screen) => screen.id === currentScreen.id);
  if (currentIndex === -1) {
    return undefined;
  }

  const nextScreen = orderedScreens[currentIndex + 1];
  return nextScreen?.id;
}
