package com.yaoai.api.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.yaoai.api.dto.project.ProjectCreateRequest;
import com.yaoai.api.dto.project.ProjectDTO;
import com.yaoai.api.dto.project.ProjectUpdateRequest;
import com.yaoai.api.service.ProjectService;
import com.yaoai.common.exception.BizException;
import com.yaoai.common.exception.ErrorCode;
import com.yaoai.domain.entity.Project;
import com.yaoai.domain.mapper.ProjectAssetMapper;
import com.yaoai.domain.mapper.ProjectMapper;
import com.yaoai.security.context.TenantContext;
import com.yaoai.storage.service.TosService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class ProjectServiceImpl implements ProjectService {

    private final ProjectMapper projectMapper;
    private final ProjectAssetMapper assetMapper;
    private final TosService tosService;

    @Override
    @Transactional
    public ProjectDTO create(ProjectCreateRequest req) {
        Long tenantId = TenantContext.get();
        Long userId = StpUtil.getLoginIdAsLong();

        Project project = new Project();
        project.setTenantId(tenantId);
        project.setUserId(userId);
        project.setName(req.getName());
        project.setDescription(req.getDescription());
        project.setStatus("draft");
        project.setStyle(req.getStyle());
        project.setAspectRatio(req.getAspectRatio());
        project.setResolution(req.getResolution());
        projectMapper.insert(project);

        return toDTO(project);
    }

    @Override
    public List<ProjectDTO> listByCurrentTenant() {
        Long tenantId = TenantContext.get();
        return projectMapper.findByTenant(tenantId).stream()
                .map(this::toDTO)
                .collect(Collectors.toList());
    }

    @Override
    public ProjectDTO getById(Long id) {
        Long tenantId = TenantContext.get();
        Project project = projectMapper.findActiveById(id, tenantId)
                .orElseThrow(() -> new BizException(ErrorCode.INVALID_PARAM, "项目不存在"));
        long assetCount = assetMapper.countByProject(id);
        String coverUrl = project.getCoverKey() != null
                ? tosService.publicUrl(project.getCoverKey())
                : null;
        return ProjectDTO.from(project, coverUrl, assetCount);
    }

    @Override
    @Transactional
    public ProjectDTO update(Long id, ProjectUpdateRequest req) {
        Long tenantId = TenantContext.get();
        Project project = projectMapper.findActiveById(id, tenantId)
                .orElseThrow(() -> new BizException(ErrorCode.INVALID_PARAM, "项目不存在"));

        if (req.getName() != null) project.setName(req.getName());
        if (req.getDescription() != null) project.setDescription(req.getDescription());
        if (req.getStyle() != null) project.setStyle(req.getStyle());
        if (req.getAspectRatio() != null) project.setAspectRatio(req.getAspectRatio());
        if (req.getResolution() != null) project.setResolution(req.getResolution());
        projectMapper.updateById(project);

        return toDTO(project);
    }

    @Override
    @Transactional
    public void delete(Long id) {
        Long tenantId = TenantContext.get();
        Project project = projectMapper.findActiveById(id, tenantId)
                .orElseThrow(() -> new BizException(ErrorCode.INVALID_PARAM, "项目不存在"));

        Project soft = new Project();
        soft.setId(project.getId());
        soft.setDeletedAt(LocalDateTime.now());
        projectMapper.updateById(soft);
    }

    private ProjectDTO toDTO(Project p) {
        long assetCount = assetMapper.countByProject(p.getId());
        String coverUrl = p.getCoverKey() != null
                ? tosService.publicUrl(p.getCoverKey())
                : null;
        return ProjectDTO.from(p, coverUrl, assetCount);
    }
}
