package com.example.demo.test;

import com.example.demo.model.UserWork;
import com.example.demo.model.TextToVideoTask;
import com.example.demo.model.ImageToVideoTask;
import com.example.demo.service.UserWorkService;
import com.example.demo.repository.UserWorkRepository;
import com.example.demo.repository.TextToVideoTaskRepository;
import com.example.demo.repository.ImageToVideoTaskRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Optional;

import static org.junit.jupiter.api.Assertions.*;

/**
 * 用户作品系统集成测试
 * 测试任务完成后作品保存到数据库的完整流程
 */
@SpringBootTest
@ActiveProfiles("test")
@Transactional
public class UserWorkIntegrationTest {

    @Autowired
    private UserWorkService userWorkService;

    @Autowired
    private UserWorkRepository userWorkRepository;

    @Autowired
    private TextToVideoTaskRepository textToVideoTaskRepository;

    @Autowired
    private ImageToVideoTaskRepository imageToVideoTaskRepository;

    /**
     * 测试文生视频任务完成后创建作品
     */
    @Test
    public void testCreateWorkFromTextToVideoTask() {
        // 创建测试任务
        TextToVideoTask task = new TextToVideoTask();
        task.setTaskId("test_txt2vid_001");
        task.setUsername("testuser");
        task.setPrompt("一只可爱的小猫在花园里玩耍");
        task.setAspectRatio("16:9");
        task.setDuration(10);
        task.setHdMode(false);
        task.setCostPoints(80);
        task.setStatus(TextToVideoTask.TaskStatus.COMPLETED);
        task.setResultUrl("https://example.com/video.mp4");
        task.setCreatedAt(LocalDateTime.now());
        task.setCompletedAt(LocalDateTime.now());
        
        // 保存任务
        task = textToVideoTaskRepository.save(task);

        // 创建作品
        String resultUrl = "https://example.com/video.mp4";
        UserWork work = userWorkService.createWorkFromTask(task.getTaskId(), resultUrl);

        // 验证作品创建
        assertNotNull(work);
        assertEquals("testuser", work.getUsername());
        assertEquals("test_txt2vid_001", work.getTaskId());
        assertEquals(UserWork.WorkType.TEXT_TO_VIDEO, work.getWorkType());
        assertEquals("一只可爱的小猫在花园里玩耍", work.getPrompt());
        assertEquals(resultUrl, work.getResultUrl());
        assertEquals("10s", work.getDuration());
        assertEquals("16:9", work.getAspectRatio());
        assertEquals("SD", work.getQuality());
        assertEquals(80, work.getPointsCost());
        assertEquals(UserWork.WorkStatus.COMPLETED, work.getStatus());
        assertNotNull(work.getCompletedAt());

        // 验证作品已保存到数据库
        Optional<UserWork> savedWork = userWorkRepository.findByTaskId(task.getTaskId());
        assertTrue(savedWork.isPresent());
        assertEquals(work.getId(), savedWork.get().getId());
    }

    /**
     * 测试图生视频任务完成后创建作品
     */
    @Test
    public void testCreateWorkFromImageToVideoTask() {
        // 创建测试任务
        ImageToVideoTask task = new ImageToVideoTask();
        task.setTaskId("test_img2vid_001");
        task.setUsername("testuser");
        task.setPrompt("美丽的风景");
        task.setAspectRatio("9:16");
        task.setDuration(15);
        task.setHdMode(true);
        task.setCostPoints(240);
        task.setStatus(ImageToVideoTask.TaskStatus.COMPLETED);
        task.setResultUrl("https://example.com/video2.mp4");
        task.setCreatedAt(LocalDateTime.now());
        task.setCompletedAt(LocalDateTime.now());
        
        // 保存任务
        task = imageToVideoTaskRepository.save(task);

        // 创建作品
        String resultUrl = "https://example.com/video2.mp4";
        UserWork work = userWorkService.createWorkFromTask(task.getTaskId(), resultUrl);

        // 验证作品创建
        assertNotNull(work);
        assertEquals("testuser", work.getUsername());
        assertEquals("test_img2vid_001", work.getTaskId());
        assertEquals(UserWork.WorkType.IMAGE_TO_VIDEO, work.getWorkType());
        assertEquals("美丽的风景", work.getPrompt());
        assertEquals(resultUrl, work.getResultUrl());
        assertEquals("15s", work.getDuration());
        assertEquals("9:16", work.getAspectRatio());
        assertEquals("HD", work.getQuality());
        assertEquals(240, work.getPointsCost());
        assertEquals(UserWork.WorkStatus.COMPLETED, work.getStatus());
        assertNotNull(work.getCompletedAt());

        // 验证作品已保存到数据库
        Optional<UserWork> savedWork = userWorkRepository.findByTaskId(task.getTaskId());
        assertTrue(savedWork.isPresent());
        assertEquals(work.getId(), savedWork.get().getId());
    }

    /**
     * 测试重复创建作品的处理
     */
    @Test
    public void testDuplicateWorkCreation() {
        // 创建测试任务
        TextToVideoTask task = new TextToVideoTask();
        task.setTaskId("test_duplicate_001");
        task.setUsername("testuser");
        task.setPrompt("测试重复创建");
        task.setAspectRatio("16:9");
        task.setDuration(10);
        task.setHdMode(false);
        task.setCostPoints(80);
        task.setStatus(TextToVideoTask.TaskStatus.COMPLETED);
        task.setResultUrl("https://example.com/video.mp4");
        task.setCreatedAt(LocalDateTime.now());
        task.setCompletedAt(LocalDateTime.now());
        
        // 保存任务
        task = textToVideoTaskRepository.save(task);

        // 第一次创建作品
        UserWork work1 = userWorkService.createWorkFromTask(task.getTaskId(), "https://example.com/video.mp4");
        assertNotNull(work1);

        // 第二次创建作品（应该返回已存在的作品）
        UserWork work2 = userWorkService.createWorkFromTask(task.getTaskId(), "https://example.com/video.mp4");
        assertNotNull(work2);
        assertEquals(work1.getId(), work2.getId());

        // 验证数据库中只有一个作品
        long count = userWorkRepository.count();
        assertEquals(1, count);
    }

    /**
     * 测试作品标题生成
     */
    @Test
    public void testWorkTitleGeneration() {
        // 测试长标题截断
        String longPrompt = "这是一个非常长的提示词，应该被截断到20个字符以内";
        TextToVideoTask task = new TextToVideoTask();
        task.setTaskId("test_title_001");
        task.setUsername("testuser");
        task.setPrompt(longPrompt);
        task.setAspectRatio("16:9");
        task.setDuration(10);
        task.setHdMode(false);
        task.setCostPoints(80);
        task.setStatus(TextToVideoTask.TaskStatus.COMPLETED);
        task.setResultUrl("https://example.com/video.mp4");
        task.setCreatedAt(LocalDateTime.now());
        task.setCompletedAt(LocalDateTime.now());
        
        task = textToVideoTaskRepository.save(task);

        UserWork work = userWorkService.createWorkFromTask(task.getTaskId(), "https://example.com/video.mp4");
        
        // 验证标题被正确截断
        assertTrue(work.getTitle().length() <= 23); // 20个字符 + "..."
        assertTrue(work.getTitle().endsWith("..."));

        // 测试空标题处理
        task.setPrompt("");
        task.setTaskId("test_title_002");
        task = textToVideoTaskRepository.save(task);

        UserWork work2 = userWorkService.createWorkFromTask(task.getTaskId(), "https://example.com/video.mp4");
        assertEquals("未命名作品", work2.getTitle());
    }

    /**
     * 测试获取用户作品列表
     */
    @Test
    public void testGetUserWorks() {
        // 创建多个测试作品
        for (int i = 1; i <= 5; i++) {
            TextToVideoTask task = new TextToVideoTask();
            task.setTaskId("test_list_" + i);
            task.setUsername("testuser");
            task.setPrompt("测试作品 " + i);
            task.setAspectRatio("16:9");
            task.setDuration(10);
            task.setHdMode(false);
            task.setCostPoints(80);
            task.setStatus(TextToVideoTask.TaskStatus.COMPLETED);
            task.setResultUrl("https://example.com/video" + i + ".mp4");
            task.setCreatedAt(LocalDateTime.now());
            task.setCompletedAt(LocalDateTime.now());
            
            task = textToVideoTaskRepository.save(task);
            userWorkService.createWorkFromTask(task.getTaskId(), task.getResultUrl());
        }

        // 获取用户作品列表
        var works = userWorkService.getUserWorks("testuser", 0, 10);
        
        // 验证结果
        assertEquals(5, works.getTotalElements());
        assertEquals(1, works.getTotalPages());
        assertEquals(5, works.getContent().size());
        
        // 验证按创建时间倒序排列
        var workList = works.getContent();
        for (int i = 0; i < workList.size() - 1; i++) {
            assertTrue(workList.get(i).getCreatedAt().isAfter(workList.get(i + 1).getCreatedAt()) ||
                      workList.get(i).getCreatedAt().isEqual(workList.get(i + 1).getCreatedAt()));
        }
    }

    /**
     * 测试作品统计信息
     */
    @Test
    public void testWorkStats() {
        // 创建不同状态的测试作品
        String[] taskIds = {"test_stats_1", "test_stats_2", "test_stats_3"};
        String[] statuses = {"COMPLETED", "COMPLETED", "FAILED"};
        int[] points = {80, 160, 240};

        for (int i = 0; i < taskIds.length; i++) {
            TextToVideoTask task = new TextToVideoTask();
            task.setTaskId(taskIds[i]);
            task.setUsername("testuser");
            task.setPrompt("测试统计 " + (i + 1));
            task.setAspectRatio("16:9");
            task.setDuration(10);
            task.setHdMode(false);
            task.setCostPoints(points[i]);
            if ("COMPLETED".equals(statuses[i])) {
                task.setStatus(TextToVideoTask.TaskStatus.COMPLETED);
            } else if ("FAILED".equals(statuses[i])) {
                task.setStatus(TextToVideoTask.TaskStatus.FAILED);
            }
            task.setResultUrl("https://example.com/video" + (i + 1) + ".mp4");
            task.setCreatedAt(LocalDateTime.now());
            task.setCompletedAt(LocalDateTime.now());
            
            task = textToVideoTaskRepository.save(task);
            
            if ("COMPLETED".equals(statuses[i])) {
                userWorkService.createWorkFromTask(task.getTaskId(), task.getResultUrl());
            }
        }

        // 获取统计信息
        var stats = userWorkService.getUserWorkStats("testuser");
        
        // 验证统计结果
        assertEquals(2L, stats.get("completedCount"));
        assertEquals(0L, stats.get("processingCount"));
        assertEquals(0L, stats.get("failedCount"));
        assertEquals(240L, stats.get("totalPointsCost")); // 80 + 160
        assertEquals(2L, stats.get("totalCount"));
        assertEquals(0L, stats.get("publicCount"));
    }
}
