package cn.iocoder.yudao.module.asset.service.assetinfo;

import cn.hutool.core.util.IdUtil;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.asset.controller.admin.assetinfo.vo.AssetInfoPageReqVO;
import cn.iocoder.yudao.module.asset.controller.admin.assetinfo.vo.AssetInfoRespVO;
import cn.iocoder.yudao.module.asset.controller.admin.assetinfo.vo.AssetInfoRetireReqVO;
import cn.iocoder.yudao.module.asset.controller.admin.assetinfo.vo.AssetInfoSaveReqVO;
import cn.iocoder.yudao.module.asset.dal.dataobject.assetinfo.AssetInfoDO;
import cn.iocoder.yudao.module.asset.dal.mysql.assetinfo.AssetInfoMapper;
import cn.iocoder.yudao.module.asset.enums.AssetStateEnum;
import cn.iocoder.yudao.module.asset.enums.AssetStatusEnum;
import cn.iocoder.yudao.module.employee.api.EmployeeApi;
import cn.iocoder.yudao.module.employee.api.dto.EmployeeRespDTO;
import cn.iocoder.yudao.module.infra.api.file.FileApi;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.asset.enums.ErrorCodeConstants.INFO_NOT_EXISTS;
import static cn.iocoder.yudao.module.asset.enums.ErrorCodeConstants.OCCUPIED_ASSET_NOT_ALLOWED_DELETE;

/**
 * 固定资产信息 Service 实现类
 *
 * @author dp
 */
@Service
@Validated
public class AssetInfoServiceImpl implements AssetInfoService {

    @Resource
    private AssetInfoMapper infoMapper;

    @Resource
    private EmployeeApi employeeApi;

    @Resource
    private FileApi fileApi;

    @Override
    public Long createInfo(AssetInfoSaveReqVO createReqVO) {
        // 获取当前登录用户ID
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        // 通过用户ID获取当前登录员工信息
        EmployeeRespDTO loginEmployee = employeeApi.getEmployeeByUserId(loginUserId);

        // 将创建请求对象转换为资产信息实体对象
        AssetInfoDO info = BeanUtils.toBean(createReqVO, AssetInfoDO.class);

        // 生成资产信息的唯一标识（UUID），使用当前日期和随机UUID组合
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        String format = formatter.format(LocalDateTime.now());
        info.setAssetInfoUuid(format + IdUtil.fastSimpleUUID());

        // 设置资产状态为可用
        info.setAssetState(AssetStateEnum.AVAILABLE.getState());

        // 单据状态
        info.setStatus(AssetStatusEnum.COMPLETED.getStatus());

        // 设置创建人为当前登录员工
        info.setCreator(String.valueOf(loginEmployee.getId()));

        // 插入资产信息到数据库
        infoMapper.insert(info);

        // 更新文件业务关系
        fileApi.updateFileBiz(createReqVO.getFileIdList(), info.getAssetInfoUuid());

        // 返回创建的资产信息的ID
        return info.getId();
    }
    @Override
    public void updateInfo(AssetInfoSaveReqVO updateReqVO) {
        // 校验存在
        AssetInfoDO assetInfoDO = validateInfoExists(updateReqVO.getId());
        // 更新
        AssetInfoDO updateObj = BeanUtils.toBean(updateReqVO, AssetInfoDO.class);

        // 附件
        fileApi.updateFileBiz(updateReqVO.getFileIdList(), assetInfoDO.getAssetInfoUuid());

        infoMapper.updateById(updateObj);
    }

    @Override
    public void availableOrOccupiedAssetInfo(AssetInfoDO updateReqVO) {
        // 校验存在
        AssetInfoDO assetInfoDO = validateInfoExists(updateReqVO.getId());
        LambdaUpdateWrapper<AssetInfoDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.set(AssetInfoDO::getAssetState, updateReqVO.getAssetState())
                .set(AssetInfoDO::getReceiveEmployeeId, updateReqVO.getReceiveEmployeeId())
                .set(AssetInfoDO::getReceiveInfoId, updateReqVO.getReceiveInfoId())
                .eq(AssetInfoDO::getId, updateReqVO.getId());
       infoMapper.update(lambdaUpdateWrapper);
    }

    @Override
    public void deleteInfo(Long id) {
        // 校验存在
        AssetInfoDO assetInfoDO = validateInfoExists(id);
        // 校验能否删除
        // 占用中的不能删除
        if (AssetStateEnum.OCCUPIED.getState().equals(assetInfoDO.getAssetState())) {
            throw exception(OCCUPIED_ASSET_NOT_ALLOWED_DELETE);
        }
        // 领用中的资产不能删除
        // 删除
        infoMapper.deleteById(id);
    }

    private AssetInfoDO validateInfoExists(Long id) {
        AssetInfoDO assetInfoDO = infoMapper.selectById(id);
        if (assetInfoDO == null) {
            throw exception(INFO_NOT_EXISTS);
        }
        return assetInfoDO;
    }

    @Override
    public AssetInfoDO getInfo(Long id) {
        return infoMapper.selectById(id);
    }

    @Override
    public PageResult<AssetInfoRespVO> getInfoPage(AssetInfoPageReqVO pageReqVO) {
        // 分页起始位置
        pageReqVO.setPageNo((pageReqVO.getPageNo() - 1) * pageReqVO.getPageSize());

        // 查询总记录数
        long pageCount = -1;
        if (!PageParam.PAGE_SIZE_NONE.equals(pageReqVO.getPageSize())) {
            pageCount = infoMapper.selectPageCount(pageReqVO);
        }

        // 查询分页数据
        List<AssetInfoRespVO> pageList = infoMapper.selectPageList(pageReqVO);

        return new PageResult<>(pageList, pageCount);
    }

    @Override
    public void retireInfo(AssetInfoRetireReqVO retireReqVO) {
        Long id = retireReqVO.getAssetInfoId();
        AssetInfoDO assetInfoDO = validateInfoExists(id);
        if (AssetStateEnum.OCCUPIED.getState().equals(assetInfoDO.getAssetState())) {
            throw exception(new ErrorCode(OCCUPIED_ASSET_NOT_ALLOWED_DELETE.getCode(), "资产正在使用，不能报废"));
        }
        if (AssetStateEnum.RETIRED.getState().equals(assetInfoDO.getAssetState())) {
            throw exception(new ErrorCode(OCCUPIED_ASSET_NOT_ALLOWED_DELETE.getCode(), "资产已报废，不能重复报废"));
        }
        AssetInfoDO build = AssetInfoDO.builder()
                .id(id)
                .assetState(AssetStateEnum.RETIRED.getState())
                .retirementDate(retireReqVO.getRetirementDate())
                .retirementReason(retireReqVO.getRetirementReason())
                .build();
        infoMapper.updateById(build);
    }

}