package com.kt.event.content.biz.service.mock;

import com.kt.event.content.biz.domain.Content;
import com.kt.event.content.biz.domain.GeneratedImage;
import com.kt.event.content.biz.domain.ImageStyle;
import com.kt.event.content.biz.domain.Job;
import com.kt.event.content.biz.domain.Platform;
import com.kt.event.content.biz.dto.ContentCommand;
import com.kt.event.content.biz.dto.JobInfo;
import com.kt.event.content.biz.usecase.in.GenerateImagesUseCase;
import com.kt.event.content.biz.usecase.out.ContentWriter;
import com.kt.event.content.biz.usecase.out.JobWriter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Profile;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

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

/**
 * Mock 이미지 생성 서비스 (테스트용)
 * 실제 Kafka 연동 전까지 사용
 *
 * 테스트를 위해 실제로 Content와 GeneratedImage를 생성합니다.
 */
@Slf4j
@Service
@Profile({"local", "test"})
@RequiredArgsConstructor
public class MockGenerateImagesService implements GenerateImagesUseCase {

    private final JobWriter jobWriter;
    private final ContentWriter contentWriter;

    @Override
    public JobInfo execute(ContentCommand.GenerateImages command) {
        log.info("[MOCK] 이미지 생성 요청: eventDraftId={}, styles={}, platforms={}",
                command.getEventDraftId(), command.getStyles(), command.getPlatforms());

        // Mock Job 생성
        String jobId = "job-mock-" + UUID.randomUUID().toString().substring(0, 8);

        Job job = Job.builder()
                .id(jobId)
                .eventDraftId(command.getEventDraftId())
                .jobType("image-generation")
                .status(Job.Status.PENDING)
                .progress(0)
                .createdAt(java.time.LocalDateTime.now())
                .updatedAt(java.time.LocalDateTime.now())
                .build();

        // Job 저장
        Job savedJob = jobWriter.save(job);
        log.info("[MOCK] Job 생성 완료: jobId={}", jobId);

        // 비동기로 이미지 생성 시뮬레이션
        processImageGeneration(jobId, command);

        return JobInfo.from(savedJob);
    }

    @Async
    private void processImageGeneration(String jobId, ContentCommand.GenerateImages command) {
        try {
            log.info("[MOCK] 이미지 생성 시작: jobId={}", jobId);

            // 1초 대기 (이미지 생성 시뮬레이션)
            Thread.sleep(1000);

            // Content 생성 또는 조회
            Content content = Content.builder()
                    .eventDraftId(command.getEventDraftId())
                    .eventTitle("Mock 이벤트 제목 " + command.getEventDraftId())
                    .eventDescription("Mock 이벤트 설명입니다. 테스트를 위한 Mock 데이터입니다.")
                    .createdAt(java.time.LocalDateTime.now())
                    .updatedAt(java.time.LocalDateTime.now())
                    .build();
            Content savedContent = contentWriter.save(content);
            log.info("[MOCK] Content 생성 완료: contentId={}", savedContent.getId());

            // 스타일 x 플랫폼 조합으로 이미지 생성
            List<ImageStyle> styles = command.getStyles() != null && !command.getStyles().isEmpty()
                    ? command.getStyles()
                    : List.of(ImageStyle.FANCY, ImageStyle.SIMPLE);

            List<Platform> platforms = command.getPlatforms() != null && !command.getPlatforms().isEmpty()
                    ? command.getPlatforms()
                    : List.of(Platform.INSTAGRAM, Platform.KAKAO);

            List<GeneratedImage> images = new ArrayList<>();
            int count = 0;
            for (ImageStyle style : styles) {
                for (Platform platform : platforms) {
                    count++;
                    String mockCdnUrl = String.format(
                            "https://mock-cdn.azure.com/images/%d/%s_%s_%s.png",
                            command.getEventDraftId(),
                            style.name().toLowerCase(),
                            platform.name().toLowerCase(),
                            UUID.randomUUID().toString().substring(0, 8)
                    );

                    GeneratedImage image = GeneratedImage.builder()
                            .eventDraftId(command.getEventDraftId())
                            .style(style)
                            .platform(platform)
                            .cdnUrl(mockCdnUrl)
                            .prompt(String.format("Mock prompt for %s style on %s platform", style, platform))
                            .selected(false)
                            .createdAt(java.time.LocalDateTime.now())
                            .updatedAt(java.time.LocalDateTime.now())
                            .build();

                    // 첫 번째 이미지를 선택된 이미지로 설정
                    if (count == 1) {
                        image.select();
                    }

                    GeneratedImage savedImage = contentWriter.saveImage(image);
                    images.add(savedImage);
                    log.info("[MOCK] 이미지 생성: imageId={}, style={}, platform={}",
                            savedImage.getId(), style, platform);
                }
            }

            // Job 상태 업데이트: COMPLETED
            Job completedJob = Job.builder()
                    .id(jobId)
                    .eventDraftId(command.getEventDraftId())
                    .jobType("image-generation")
                    .status(Job.Status.COMPLETED)
                    .progress(100)
                    .resultMessage(String.format("%d개의 이미지가 성공적으로 생성되었습니다.", images.size()))
                    .createdAt(java.time.LocalDateTime.now())
                    .updatedAt(java.time.LocalDateTime.now())
                    .build();

            jobWriter.save(completedJob);
            log.info("[MOCK] Job 완료: jobId={}, 생성된 이미지 수={}", jobId, images.size());

        } catch (Exception e) {
            log.error("[MOCK] 이미지 생성 실패: jobId={}", jobId, e);

            // Job 상태 업데이트: FAILED
            Job failedJob = Job.builder()
                    .id(jobId)
                    .eventDraftId(command.getEventDraftId())
                    .jobType("image-generation")
                    .status(Job.Status.FAILED)
                    .progress(0)
                    .errorMessage(e.getMessage())
                    .createdAt(java.time.LocalDateTime.now())
                    .updatedAt(java.time.LocalDateTime.now())
                    .build();

            jobWriter.save(failedJob);
        }
    }
}
