package com.bcxin.tenant.domain.services.impls;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.bcxin.Infrastructures.UnitWork;
import com.bcxin.Infrastructures.exceptions.ArgumentTenantException;
import com.bcxin.Infrastructures.exceptions.BadTenantException;
import com.bcxin.Infrastructures.exceptions.NotFoundTenantException;
import com.bcxin.Infrastructures.utils.AuthUtil;
import com.bcxin.tenant.domain.dto.XlcpReportDto;
import com.bcxin.tenant.domain.entities.EmployeeEntity;
import com.bcxin.tenant.domain.entities.XlcpEntity;
import com.bcxin.tenant.domain.repositories.*;
import com.bcxin.tenant.domain.services.XlcpService;
import com.bcxin.tenant.domain.services.commands.xlcp.CreateXlcpCommand;
import com.bcxin.tenant.domain.services.commands.xlcp.UpdateXlcpCommand;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;

@Service
public class XlcpServiceImpl implements XlcpService {
    private final XlcpRepository xlcpRepository;
    private final EmployeeRepository employeeRepository;
    private final UnitWork unitWork;


    public XlcpServiceImpl(XlcpRepository xlcpRepository,
                           EmployeeRepository employeeRepository,
                           UnitWork unitWork) {
        this.xlcpRepository = xlcpRepository;
        this.employeeRepository = employeeRepository;
        this.unitWork = unitWork;
    }

    @Override
    public void dispatch(CreateXlcpCommand command) {
        command.validate();
        this.unitWork.executeTran(() -> {
            XlcpEntity xlcp =
                    XlcpEntity.create(command.getSerialNumber(),command.getProjectName(),
                            command.getOrganizationId(), command.getEmployeeId(), command.getName(),
                            command.getNumber()
                            ,command.getFileUrl(), command.getSuggestion(), command.getContent(), command.getResult(),command.getResultRuleTip());
            xlcp.assignCreator(AuthUtil.getCurrentOperator());
            xlcp.assignModifier(AuthUtil.getCurrentOperator());

            this.xlcpRepository.save(xlcp);
        });
    }

    @Override
    public void dispatch(UpdateXlcpCommand command) {
        command.validate();

        List<XlcpEntity> xlcpList = xlcpRepository.getByOrganIdAndEmployeeId(command.getOrganizationId(), command.getEmployeeId());
        if(xlcpList.size()==0){
            throw new NotFoundTenantException("找不到测评信息");
        }
        XlcpEntity xlcp = xlcpList.get(0);
        this.unitWork.executeTran(() -> {
            xlcp.change(command.getFileUrl(), command.getSuggestion(), command.getContent());
            xlcp.assignModifier(AuthUtil.getCurrentOperator());
            this.xlcpRepository.save(xlcp);
        });
    }

    @Override
    public void dispatch(String id, String fileUrl) {
        Optional<XlcpEntity> xlcpOptional = xlcpRepository.findById(id);
        if (!xlcpOptional.isPresent()) {
            throw new BadTenantException("测评记录不存在");
        }
        XlcpEntity xlcp = xlcpOptional.get();
        this.unitWork.executeTran(() -> {
            xlcp.change(fileUrl, xlcp.getSuggestion(), xlcp.getContent());
            this.xlcpRepository.save(xlcp);
        });
    }

    /**
     * <b> 雇员是否存在期限内测评数据（固定6个月内） </b>
     * @author ZXF
     * @create 2025/05/26 0026 14:06
     * @version
     * @注意事项 </b>
     */
    @Override
    public int isWithinTheDeadline(String empId) {
        if (!StringUtils.hasLength(empId)) {
            throw new ArgumentTenantException("雇员不能为空");
        }
        //如果没做过不验证
        List<XlcpEntity> list1 = xlcpRepository.countWithinTheDeadlineOfEmployeeId(empId, DateUtil.offset(new Date(), DateField.MONTH, -240));
        if (list1.isEmpty()) {
            return 1;//true;
        }
        //如果做过需要查是否过期
        List<XlcpEntity> list = xlcpRepository.countWithinTheDeadlineOfEmployeeId(empId, DateUtil.offset(new Date(), DateField.MONTH, -6));
        if (list.isEmpty()) {
            return 2;//false;
        }
        return 3;//true;
    }

    /**
     * <b> 根据雇员id和测评项目查询 </b>
     * @author ZXF
     * @create 2025/05/26 0026 14:06
     * @version
     * @param employeeId
     * @param projectName
     * @return java.util.Collection< com.bcxin.tenant.domain.dto.XlcpReportDto>
     * @注意事项 </b>
     */
    @Override
    public Collection<XlcpReportDto> findByEmployeeIdAndProjectName(String employeeId, String projectName) {
        if (!StringUtils.hasLength(employeeId)) {
            throw new ArgumentTenantException("雇员不能为空");
        }
        if (!StringUtils.hasLength(projectName)) {
            throw new ArgumentTenantException("测评项目不能为空");
        }
        Collection<XlcpEntity> list = xlcpRepository.findByEmployeeIdAndProjectName(employeeId, projectName);
        if (list.isEmpty()) {
            return Collections.emptyList();
        }
        
        Collection<XlcpReportDto> result = new ArrayList<>();
        int index = 1;
        for (XlcpEntity xlcpEntity : list) {
            result.add(XlcpReportDto.create(
                String.valueOf(index++),
                xlcpEntity.getProjectName(),
                DateUtil.formatDateTime(xlcpEntity.getCreator().getCreatedTime()),
                xlcpEntity.getFileUrl()
            ));
        }
        return result;
    }

    @Override
    public Collection<XlcpReportDto> findByThirdPath(int day) {
        if (day <= 0) {
            throw new ArgumentTenantException("天数不能为空");
        }
        Collection<XlcpEntity> list = xlcpRepository.findByTimeAndLikeName(DateUtil.offset(new Date(), DateField.DAY_OF_MONTH, -day), "%bjzgxl%");
        if (list.isEmpty()) {
            return Collections.emptyList();
        }
        Collection<XlcpReportDto> result = new ArrayList<>();
        for (XlcpEntity xlcpEntity : list) {
            result.add(XlcpReportDto.create(
                    xlcpEntity.getId(),
                    xlcpEntity.getProjectName(),
                    DateUtil.formatDateTime(xlcpEntity.getCreator().getCreatedTime()),
                    xlcpEntity.getFileUrl()
            ));
        }
        return result;
    }
}
