package kz.konturai.parser.service;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import kz.konturai.parser.config.TargetingApiConfig;
import kz.konturai.parser.exception.ABTestInsufficientDataException;
import kz.konturai.parser.model.ABTestConfig;
import kz.konturai.parser.model.TargetingAd;
import kz.konturai.parser.model.TargetingCampaign;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
@RequiredArgsConstructor
@Slf4j
public class ABTestingService {

    private final OpenAIAnalyticsService openAiService;
    private final TargetingApiConfig apiConfig;
    private final ObjectMapper objectMapper;

    public void createABTest(TargetingCampaign campaign, String adSetId) {
        log.info("Creating AB Test for campaign {} adSet {}", campaign.getId(), adSetId);
        ABTestConfig config = ABTestConfig.builder()
                .isEnabled(true)
                .variants(List.of("A", "B", "C"))
                .build();
        campaign.setAbTestConfig(config);
    }

    public String evaluateABTest(TargetingCampaign campaign) {
        log.info("Evaluating AB Test for campaign {}", campaign.getId());

        if (campaign.getPerformanceMetrics() == null || campaign.getPerformanceMetrics().getClicks() < 100) {
            throw new ABTestInsufficientDataException("Not enough clicks to statistically evaluate the A/B test");
        }

        // Placeholder logic to determine winner
        String winnerVariant = "A";
        campaign.getAbTestConfig().setWinnerVariantId(winnerVariant);
        return winnerVariant;
    }

    public List<TargetingAd> generateABVariants(String analysisContext, String objective) {
        log.info("Generating AB Variants for objective {}", objective);

        try {
            String systemPrompt = "Ты — AI копирайтер для рынка Казахстана. Создай 3 варианта одного рекламного объявления с разными подходами: " +
                    "A: Рациональный (факты, выгоды), B: Эмоциональный (боль клиента), C: Социальное доказательство (кейсы). " +
                    "Для каждого объявления верни объект с: abVariant (A,B,C), headline (макс 40 симв), primaryText (макс 125 для превью), callToAction (LEARN_MORE, SHOP_NOW, SIGN_UP, CONTACT_US, BOOK_NOW). " +
                    "Верни JSON массив объектов. Без маркдауна.";

            String instruction = "Сгенерируй A/B/C варианты креативов для кампании с целью " + objective + ". Контекст: " + analysisContext;

            String response = openAiService.generateWithInstructionWithModel(
                    "Генерация креативов",
                    instruction,
                    "ru",
                    apiConfig.getAi().getCreativesModel(),
                    systemPrompt,
                    apiConfig.getAi().getMaxCreativesTokens()
            );

            if (response != null && response.startsWith("```json")) {
                response = response.substring(7, response.lastIndexOf("```")).trim();
            }

            return objectMapper.readValue(response, new TypeReference<List<TargetingAd>>() {});

        } catch (Exception e) {
            log.error("Failed to generate AB variants", e);
            
            // Fallback definitions in case of failure
            List<TargetingAd> fallback = new ArrayList<>();
            fallback.add(createFallbackAd("A", "Рациональный заголовок", "Узнайте о наших выгодах. Жмите подробнее."));
            fallback.add(createFallbackAd("B", "Хватит переплачивать!", "Решите проблему сегодня. Жмите подробнее."));
            fallback.add(createFallbackAd("C", "Выбор 1000 клиентов", "Присоединяйтесь к нам. Жмите подробнее."));
            return fallback;
        }
    }

    private TargetingAd createFallbackAd(String variant, String headline, String text) {
        return TargetingAd.builder()
                .adId(UUID.randomUUID().toString())
                .abVariant(variant)
                .headline(headline)
                .primaryText(text)
                .callToAction("LEARN_MORE")
                .name("Option " + variant)
                .build();
    }
}
