package com.example.demo.service;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.example.demo.model.ImageToVideoTask;
import com.example.demo.model.TextToVideoTask;
import com.example.demo.model.User;
import com.example.demo.model.UserWork;
import com.example.demo.repository.ImageToVideoTaskRepository;
import com.example.demo.repository.TextToVideoTaskRepository;
import com.example.demo.repository.UserWorkRepository;

/**
 * 用户作品服务类
 */
@Service
@Transactional
public class UserWorkService {

    private static final Logger logger = LoggerFactory.getLogger(UserWorkService.class);

    @Autowired
    private UserWorkRepository userWorkRepository;

    @Autowired
    private TextToVideoTaskRepository textToVideoTaskRepository;

    @Autowired
    private UserService userService;

    @Autowired
    private ImageToVideoTaskRepository imageToVideoTaskRepository;

    /**
     * 从任务创建作品
     */
    @Transactional
    public UserWork createWorkFromTask(String taskId, String resultUrl) {
        // 检查是否已存在作品
        Optional<UserWork> existingWork = userWorkRepository.findByTaskId(taskId);
        if (existingWork.isPresent()) {
            logger.warn("作品已存在，跳过创建: {}", taskId);
            return existingWork.get();
        }

        // 尝试从文生视频任务创建作品
        Optional<TextToVideoTask> textTaskOpt = textToVideoTaskRepository.findByTaskId(taskId);
        if (textTaskOpt.isPresent()) {
            TextToVideoTask task = textTaskOpt.get();
            return createTextToVideoWork(task, resultUrl);
        }

        // 尝试从图生视频任务创建作品
        Optional<ImageToVideoTask> imageTaskOpt = imageToVideoTaskRepository.findByTaskId(taskId);
        if (imageTaskOpt.isPresent()) {
            ImageToVideoTask task = imageTaskOpt.get();
            return createImageToVideoWork(task, resultUrl);
        }

        throw new RuntimeException("找不到对应的任务: " + taskId);
    }

    /**
     * 创建文生视频作品
     */
    private UserWork createTextToVideoWork(TextToVideoTask task, String resultUrl) {
        UserWork work = new UserWork();
        work.setUserId(getUserIdByUsername(task.getUsername()));
        work.setUsername(task.getUsername());
        work.setTaskId(task.getTaskId());
        work.setWorkType(UserWork.WorkType.TEXT_TO_VIDEO);
        work.setTitle(generateTitle(task.getPrompt()));
        work.setDescription("文生视频作品");
        work.setPrompt(task.getPrompt());
        work.setResultUrl(resultUrl);
        work.setDuration(String.valueOf(task.getDuration()) + "s");
        work.setAspectRatio(task.getAspectRatio());
        work.setQuality(task.isHdMode() ? "HD" : "SD");
        work.setPointsCost(task.getCostPoints());
        work.setStatus(UserWork.WorkStatus.COMPLETED);
        work.setCompletedAt(LocalDateTime.now());

        work = userWorkRepository.save(work);
        logger.info("创建文生视频作品成功: {}, 用户: {}", work.getId(), work.getUsername());
        return work;
    }

    /**
     * 创建图生视频作品
     */
    private UserWork createImageToVideoWork(ImageToVideoTask task, String resultUrl) {
        UserWork work = new UserWork();
        work.setUserId(getUserIdByUsername(task.getUsername()));
        work.setUsername(task.getUsername());
        work.setTaskId(task.getTaskId());
        work.setWorkType(UserWork.WorkType.IMAGE_TO_VIDEO);
        work.setTitle(generateTitle(task.getPrompt()));
        work.setDescription("图生视频作品");
        work.setPrompt(task.getPrompt());
        work.setResultUrl(resultUrl);
        work.setDuration(String.valueOf(task.getDuration()) + "s");
        work.setAspectRatio(task.getAspectRatio());
        work.setQuality(Boolean.TRUE.equals(task.getHdMode()) ? "HD" : "SD");
        work.setPointsCost(task.getCostPoints());
        work.setStatus(UserWork.WorkStatus.COMPLETED);
        work.setCompletedAt(LocalDateTime.now());

        work = userWorkRepository.save(work);
        logger.info("创建图生视频作品成功: {}, 用户: {}", work.getId(), work.getUsername());
        return work;
    }

    /**
     * 根据用户名获取用户ID
     */
    private Long getUserIdByUsername(String username) {
        try {
            User user = userService.findByUsername(username);
            if (user != null) {
                return user.getId();
            }
            logger.warn("找不到用户: {}", username);
            return null;
        } catch (Exception e) {
            logger.error("获取用户ID失败: {}", username, e);
            return null;
        }
    }

    /**
     * 生成作品标题
     */
    private String generateTitle(String prompt) {
        if (prompt == null || prompt.trim().isEmpty()) {
            return "未命名作品";
        }
        
        // 取提示词的前20个字符作为标题
        String title = prompt.trim();
        if (title.length() > 20) {
            title = title.substring(0, 20) + "...";
        }
        return title;
    }

    /**
     * 获取用户作品列表
     */
    @Transactional(readOnly = true)
    public Page<UserWork> getUserWorks(String username, int page, int size) {
        Pageable pageable = PageRequest.of(page, size);
        return userWorkRepository.findByUsernameOrderByCreatedAtDesc(username, pageable);
    }

    /**
     * 获取用户作品详情
     */
    @Transactional(readOnly = true)
    public UserWork getUserWorkDetail(Long workId, String username) {
        Optional<UserWork> workOpt = userWorkRepository.findById(workId);
        if (workOpt.isEmpty()) {
            throw new RuntimeException("作品不存在");
        }

        UserWork work = workOpt.get();
        if (!work.getUsername().equals(username)) {
            throw new RuntimeException("无权访问该作品");
        }

        return work;
    }

    /**
     * 更新作品信息
     */
    @Transactional
    public UserWork updateWork(Long workId, String username, String title, String description, String tags, Boolean isPublic) {
        UserWork work = getUserWorkDetail(workId, username);
        
        if (title != null && !title.trim().isEmpty()) {
            work.setTitle(title.trim());
        }
        
        if (description != null) {
            work.setDescription(description);
        }
        
        if (tags != null) {
            work.setTags(tags);
        }
        
        if (isPublic != null) {
            work.setIsPublic(isPublic);
        }
        
        work.setUpdatedAt(LocalDateTime.now());
        work = userWorkRepository.save(work);
        
        logger.info("更新作品信息成功: {}, 用户: {}", workId, username);
        return work;
    }

    /**
     * 删除作品（软删除）
     */
    @Transactional
    public boolean deleteWork(Long workId, String username) {
        Optional<UserWork> workOpt = userWorkRepository.findById(workId);
        if (workOpt.isEmpty()) {
            return false;
        }

        UserWork work = workOpt.get();
        if (!work.getUsername().equals(username)) {
            throw new RuntimeException("无权删除该作品");
        }

        int result = userWorkRepository.softDeleteWork(workId, username, LocalDateTime.now());
        logger.info("删除作品成功: {}, 用户: {}", workId, username);
        return result > 0;
    }

    /**
     * 获取公开作品列表
     */
    @Transactional(readOnly = true)
    public Page<UserWork> getPublicWorks(int page, int size) {
        Pageable pageable = PageRequest.of(page, size);
        return userWorkRepository.findPublicWorksOrderByCreatedAtDesc(pageable);
    }

    /**
     * 根据类型获取公开作品
     */
    @Transactional(readOnly = true)
    public Page<UserWork> getPublicWorksByType(UserWork.WorkType workType, int page, int size) {
        Pageable pageable = PageRequest.of(page, size);
        return userWorkRepository.findPublicWorksByTypeOrderByCreatedAtDesc(workType, pageable);
    }

    /**
     * 搜索公开作品
     */
    @Transactional(readOnly = true)
    public Page<UserWork> searchPublicWorks(String keyword, int page, int size) {
        Pageable pageable = PageRequest.of(page, size);
        return userWorkRepository.findPublicWorksByPromptOrderByCreatedAtDesc(keyword, pageable);
    }

    /**
     * 根据标签搜索作品
     */
    @Transactional(readOnly = true)
    public Page<UserWork> searchPublicWorksByTag(String tag, int page, int size) {
        Pageable pageable = PageRequest.of(page, size);
        return userWorkRepository.findPublicWorksByTagOrderByCreatedAtDesc(tag, pageable);
    }

    /**
     * 获取热门作品
     */
    @Transactional(readOnly = true)
    public Page<UserWork> getPopularWorks(int page, int size) {
        Pageable pageable = PageRequest.of(page, size);
        return userWorkRepository.findPopularWorksOrderByViewCountDesc(pageable);
    }

    /**
     * 获取最新作品
     */
    @Transactional(readOnly = true)
    public Page<UserWork> getLatestWorks(int page, int size) {
        Pageable pageable = PageRequest.of(page, size);
        return userWorkRepository.findLatestWorksOrderByCreatedAtDesc(pageable);
    }

    /**
     * 增加浏览次数
     */
    @Transactional
    public void incrementViewCount(Long workId) {
        userWorkRepository.incrementViewCount(workId, LocalDateTime.now());
    }

    /**
     * 增加点赞次数
     */
    @Transactional
    public void incrementLikeCount(Long workId) {
        userWorkRepository.incrementLikeCount(workId, LocalDateTime.now());
    }

    /**
     * 增加下载次数
     */
    @Transactional
    public void incrementDownloadCount(Long workId) {
        userWorkRepository.incrementDownloadCount(workId, LocalDateTime.now());
    }

    /**
     * 获取用户作品统计
     */
    @Transactional(readOnly = true)
    public Map<String, Object> getUserWorkStats(String username) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            Object[] stats = userWorkRepository.getUserWorkStats(username);
            
            // 安全地处理查询结果
            if (stats != null && stats.length >= 4) {
                result.put("completedCount", stats[0] != null ? stats[0] : 0);
                result.put("processingCount", stats[1] != null ? stats[1] : 0);
                result.put("failedCount", stats[2] != null ? stats[2] : 0);
                result.put("totalPointsCost", stats[3] != null ? stats[3] : 0);
            } else {
                // 如果查询结果格式不正确，使用默认值
                result.put("completedCount", 0);
                result.put("processingCount", 0);
                result.put("failedCount", 0);
                result.put("totalPointsCost", 0);
            }
        } catch (Exception e) {
            // 如果查询失败，使用默认值
            logger.warn("获取用户作品统计失败，使用默认值: " + e.getMessage());
            result.put("completedCount", 0);
            result.put("processingCount", 0);
            result.put("failedCount", 0);
            result.put("totalPointsCost", 0);
        }
        
        result.put("totalCount", userWorkRepository.countByUsername(username));
        result.put("publicCount", userWorkRepository.countPublicWorksByUsername(username));
        
        return result;
    }

    /**
     * 清理过期失败作品
     */
    @Transactional
    public int cleanupExpiredFailedWorks() {
        LocalDateTime expiredDate = LocalDateTime.now().minusDays(30);
        return userWorkRepository.deleteExpiredFailedWorks(expiredDate);
    }

    /**
     * 根据任务ID获取作品
     */
    @Transactional(readOnly = true)
    public Optional<UserWork> getWorkByTaskId(String taskId) {
        return userWorkRepository.findByTaskId(taskId);
    }

    /**
     * 更新作品状态
     */
    @Transactional
    public void updateWorkStatus(String taskId, UserWork.WorkStatus status) {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime completedAt = status == UserWork.WorkStatus.COMPLETED ? now : null;
        
        int result = userWorkRepository.updateStatusByTaskId(taskId, status, now, completedAt);
        if (result > 0) {
            logger.info("更新作品状态成功: {} -> {}", taskId, status);
        }
    }

    /**
     * 更新作品结果URL
     */
    @Transactional
    public void updateWorkResultUrl(String taskId, String resultUrl) {
        int result = userWorkRepository.updateResultUrlByTaskId(taskId, resultUrl, LocalDateTime.now());
        if (result > 0) {
            logger.info("更新作品结果URL成功: {} -> {}", taskId, resultUrl);
        }
    }
}
