package com.ruoyi.web.work.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.work.api.util.AppUtil;
import com.ruoyi.web.work.domain.*;
import com.ruoyi.web.work.domain.dto.PositionDto;
import com.ruoyi.web.work.domain.dto.PositionQueryDto;
import com.ruoyi.web.work.domain.dto.PositionStateDto;
import com.ruoyi.web.work.domain.vo.PositionListVo;
import com.ruoyi.web.work.mapper.PositionMapper;
import com.ruoyi.web.work.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

/**
 * @author lsw
 * @date 2024-06-07
 */
@Service
public class PositionServiceImpl extends ServiceImpl<PositionMapper, Position> implements IPositionService {
    @Autowired
    private PositionMapper positionMapper;

    @Autowired
    private IColumnService columnService;

    @Autowired
    private IEnterpriseService enterpriseService;

    @Autowired
    private IUserService userService;

    @Autowired
    private IPayService payService;

    @Autowired
    private IResumeDeliverService resumeDeliverService;

    @Autowired
    private RedisCache redisCache;

    @Override
    public List<Position> selectList(Position position) {
        return positionMapper.selectList(position);
    }

    @Override
    public List<Position> manageList(Position position) {
        position.setUserId(AppUtil.getUser().getId());
        PageUtils.orderBy("id desc");
        return positionMapper.manageList(position);
    }

    @Override
    public List<PositionListVo> indexList(PositionQueryDto dto) {
        if (StringUtils.isNotEmpty(dto.getSalary())) {
            if (dto.getSalary().equals("50k以上")) {
                dto.setMin(50);
                dto.setMax(500);
            } else if (dto.getSalary().equals("不限")) {
                dto.setMin(0);
                dto.setMax(50000);
            } else {
                String salary[] = dto.getSalary().replace("k", "").split("-");
                dto.setMin(Integer.parseInt(salary[0]));
                dto.setMax(Integer.parseInt(salary[1]));
            }
        }
        return positionMapper.indexList(dto);
    }

    @Override
    public AjaxResult detail(Long id) {
        AjaxResult result = new AjaxResult();
        Position position = getById(id);
        if (position == null || position.getState() != 0 || position.getAudit() != 1) {
            return AjaxResult.error("职位不存在或已下架");
        }
        if (position.getType() == 0) {
            Enterprise enterprise = enterpriseService.getById(position.getUserId());
            result.put("enterprise", enterprise);
        }
        result.put("position", position);
        return AjaxResult.success(result);
    }

    @Transactional
    @Override
    public AjaxResult manageAdd(PositionDto dto) {
        Platform platform = redisCache.getCacheObject(CacheConstants.APP_PLATFORM);
        if (AppUtil.getUser().getIsAuthentication() != 1) {
            return AjaxResult.error(7878, "发布全职或兼职需要实名认证");
        }
        User user = userService.getById(AppUtil.getUser().getId());
        Position position = new Position();
        BeanUtils.copyProperties(dto, position);
        //全职
        if (dto.getType() == 0) {
            if (user.getType() != 1) {
                return AjaxResult.error("只有企业用户才能发布全职");
            }
            if (user.getIsEnterprise() != 1) {
                return AjaxResult.error(7979, "请先完成企业认证");
            }
        }
        //兼职
        if (dto.getType() == 1) {
            Object salaryObj = new BigDecimal(dto.getSalary());
            if (!(salaryObj instanceof BigDecimal)) {
                return AjaxResult.error("兼职金额不是一个有效类型");
            }
            BigDecimal salary = (BigDecimal) salaryObj;
            if (salary.compareTo(BigDecimal.ZERO) <= 0) {
                return AjaxResult.error("兼职金额必须大于0");
            }
            if (salary.stripTrailingZeros().scale() > 2) {
                return AjaxResult.error("兼职金额最多只能有两位小数");
            }
            //计算服务费
            BigDecimal serviceMoney = platform.getPartTimeService().divide(new BigDecimal("100")).multiply(salary).setScale(2, RoundingMode.HALF_UP);
            //计算总费用
            BigDecimal totalMoney = serviceMoney.add(salary).setScale(2, RoundingMode.HALF_UP);
            if (totalMoney.compareTo(user.getMoney()) > 0) {
                return AjaxResult.error(8080, "余额不足请先充值");
            }
            if (!serviceMoney.equals(dto.getServiceMoney()) || !totalMoney.equals(dto.getRealMoney())) {
                return AjaxResult.error("扣除金额异常");
            }
            position.setRate(platform.getPartTimeService());
            position.setServiceMoney(serviceMoney);
        }
        //根据地区名称找到对应的Ancestors
        if (StringUtils.isNotEmpty(position.getRegionName())) {
            Column region = columnService.selectRegion(new Column().setTitle(position.getRegionName()).setLevel(3));
            if (region != null) {
                position.setAncestors(region.getAncestors() + "," + region.getId());
            }
        }
        //全职薪资
        if (!position.getSalary().equals("面议") && position.getType() == 0) {
            String salary[] = position.getSalary().replace("k", "").split("-");
            position.setMin(Integer.parseInt(salary[0]));
            position.setMax(Integer.parseInt(salary[1]));
        }
        position.setUserId(AppUtil.getUser().getId());
        position.setState(0);
        position.setAudit(0);
        position.setRecommend(0);
        if (!save(position)) {
            throw new ServiceException("发布职位失败,请联系平台");
        }
        //发布兼职更新账户和保存支出记录
        if (dto.getType() == 1) {
            //更新用户账户余额
            user.setMoney(user.getMoney().subtract(dto.getRealMoney()));
            if (!userService.updateById(user)) {
                throw new ServiceException("更新账户余额失败,请联系平台");
            }
            //添加支出记录
            Pay pay = new Pay();
            pay.setUserId(user.getId());
            pay.setMoney(dto.getRealMoney());
            pay.setServiceMoney(dto.getServiceMoney());
            pay.setRate(platform.getCashOutService());
            pay.setState(1);
            pay.setType(1);
            pay.setTitle(position.getTitle());
            pay.setVersion(System.currentTimeMillis());
            pay.setPositionId(position.getId());
            pay.setNums(StringUtils.generateNumber());
            if (!payService.save(pay)) {
                throw new ServiceException("保存支出记录失败,请联系平台");
            }
        }
        return AjaxResult.success();
    }

    @Override
    public AjaxResult manageEdit(PositionDto dto) {
        Position position = getById(dto.getId());
        if (position == null || !position.getUserId().equals(AppUtil.getUser().getId())) {
            return AjaxResult.error("职位不存在或非法操作");
        }
        if (dto.getType() == 1 && !position.getSalary().equals(dto.getSalary())) {
            return AjaxResult.error("兼职不允许编辑金额,如需修改金额请删除后重新发");
        }
        if (position.getAudit() == 1) {
            return AjaxResult.error("该职位已审核通过不允许编辑");
        }
        BeanUtils.copyProperties(dto, position);
        Column region = columnService.selectRegion(new Column().setTitle(position.getRegionName()).setLevel(3));
        if (region != null) {
            position.setAncestors(region.getAncestors() + "," + region.getId());
        }
        //全职薪资
        if (!position.getSalary().equals("面议") && position.getType() == 0) {
            String salary[] = position.getSalary().replace("k", "").split("-");
            position.setMin(Integer.parseInt(salary[0]));
            position.setMax(Integer.parseInt(salary[1]));
        }
        position.setUserId(AppUtil.getUser().getId());
        if (!updateById(position)) {
            throw new ServiceException("编辑职位失败");
        }
        return AjaxResult.success();
    }

    @Override
    public AjaxResult manageDetail(Long id) {
        Position position = getById(id);
        if (position == null || !position.getUserId().equals(AppUtil.getUser().getId())) {
            return AjaxResult.error("职位不存在或非法操作");
        }
        return AjaxResult.success(position);
    }

    @Transactional
    @Override
    public AjaxResult manageRemove(Long id) {
        Position position = getById(id);
        if (position == null || !position.getUserId().equals(AppUtil.getUser().getId())) {
            return AjaxResult.error("职位不存在或非法操作");
        }
        if (position.getType() == 1 && (position.getAudit() == 1 || position.getComplete() != 0)) {
            return AjaxResult.error("当前兼职不可删除");
        }
        if (!removeById(id)) {
            throw new ServiceException("删除职位失败,请联系平台");
        }
        //删除兼职退回余额
        if (position.getType() == 1) {
            List<ResumeDeliver> list = resumeDeliverService.selectList(new ResumeDeliver().setPositionId(position.getId()).setIsAccept(1));
            if (!list.isEmpty() && list.size() > 0) {
                throw new ServiceException("删除职位失败,已经有人接单");
            }
            User user = userService.getById(position.getUserId());
            user.setMoney(user.getMoney().add(new BigDecimal(position.getSalary())));
            if (!userService.updateById(user)) {
                throw new ServiceException("更新账户余额失败,请联系平台");
            }
            //添加退回记录
            Pay pay = new Pay();
            pay.setUserId(user.getId());
            pay.setMoney(new BigDecimal(position.getSalary()));
            pay.setState(1);
            pay.setType(4);
            pay.setTitle(position.getTitle());
            pay.setVersion(System.currentTimeMillis());
            pay.setPositionId(position.getId());
            pay.setNums(StringUtils.generateNumber());
            if (!payService.save(pay)) {
                throw new ServiceException("保存退回记录失败,请联系平台");
            }
        }
        return AjaxResult.success();
    }

    @Override
    public AjaxResult manageState(PositionStateDto dto) {
        Position position = getById(dto.getId());
        if (position == null || !position.getUserId().equals(AppUtil.getUser().getId())) {
            return AjaxResult.error("职位不存在或非法操作");
        }
        if (dto.getType() == 1) {
            return AjaxResult.error("兼职不允许关闭");
        }
        position.setState(dto.getState());
        if (!updateById(position)) {
            throw new ServiceException("启用或关闭职位失败,请联系平台");
        }
        return AjaxResult.success();
    }
}
