package com.yccrc.kede.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yccrc.common.constant.UserConstants;
import com.yccrc.common.core.domain.entity.SysUser;
import com.yccrc.common.exception.ServiceException;
import com.yccrc.common.utils.PageUtils;
import com.yccrc.common.utils.SecurityUtils;
import com.yccrc.kede.domain.Attach;
import com.yccrc.kede.domain.Enterprise;
import com.yccrc.kede.domain.EnterpriseLog;
import com.yccrc.kede.enums.AttachTypeEnum;
import com.yccrc.kede.enums.UserTypeEnum;
import com.yccrc.kede.mapper.EnterpriseMapper;
import com.yccrc.kede.service.IAttachService;
import com.yccrc.kede.service.IEnterpriseLogService;
import com.yccrc.kede.service.IEnterpriseService;
import com.yccrc.kede.service.IRegionService;
import com.yccrc.kede.vo.EnterpriseAdminVO;
import com.yccrc.kede.vo.EnterpriseDetailVO;
import com.yccrc.kede.vo.IndexRptVO;
import com.yccrc.system.service.ISysRoleService;
import com.yccrc.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 企业信息Service业务层处理
 *
 * @author yccrc
 * @date 2022-04-25
 */
@Service
@Slf4j
public class EnterpriseServiceImpl extends ServiceImpl<EnterpriseMapper, Enterprise> implements IEnterpriseService {

    @Autowired
    ISysUserService userService;

    @Autowired
    IAttachService attachService;

    @Autowired
    ISysRoleService sysRoleService;
    @Autowired
    private IRegionService regionService;

    @Autowired
    private IEnterpriseLogService enterpriseLogService;


    @Override
    @Transactional
    public boolean saveAdminEnterprise(EnterpriseAdminVO entity) {
        log.info("企业录入信息:{}", JSON.toJSONString(entity));

        SysUser user = BeanUtil.copyProperties(entity, SysUser.class);
        if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user.getUserName()))) {
            throw new ServiceException("新增用户'" + user.getUserName() + "'失败，登录账号已存在");
        }
        // else if (StringUtils.isNotEmpty(user.getPhonenumber())) {
        //     throw new ServiceException("新增用户手机'" + entity.getPhonenumber() + "'失败，该号码已存在");
        // }

        user.setUserType(UserTypeEnum.ENT_ADMIN);
        user.setCreateBy(entity.getCreateBy());
        // user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        // 2023-07-04:能否用企业统一信用代码作为用户名，然后默认密码123456
        user.setUserName(entity.getLicense());
        user.setPassword(SecurityUtils.encryptPassword("123456"));
        //绑定角色(企业用户)
        log.info("用户注册:{}", JSON.toJSONString(user));
        //   user.setRoleIds(new Long[] {4l});
        userService.registerUser(user);

        sysRoleService.insertAuthUsers(4l, new Long[]{user.getUserId()});


        Enterprise enterprise = BeanUtil.copyProperties(entity, Enterprise.class);

        baseMapper.insert(enterprise);

        log.info("更新用户与企业绑定关系");
        userService.lambdaUpdate().set(SysUser::getScopeId, enterprise.getId()).eq(SysUser::getUserId, user.getUserId()).update();

        if (!CollectionUtil.isEmpty(entity.getAttachIds())) {
            log.info("更新附件绑定关系");

            attachService.lambdaUpdate().set(Attach::getAttachType, AttachTypeEnum.ENT)
                    .set(Attach::getDataId, enterprise.getId())
                    .in(Attach::getId, entity.getAttachIds()).update();
        }

        return true;
    }

    @Override
    @Transactional
    public boolean saveEnterprise(EnterpriseDetailVO entity) {
        log.info("企业录入信息:{}", JSON.toJSONString(entity));

        if (!StrUtil.isEmpty(entity.getLicense()) && checkLicense(entity.getLicense())) {
            throw new ServiceException("企业信用代码重复，请重新输入。");
        }

        Enterprise enterprise = BeanUtil.copyProperties(entity, Enterprise.class);
        enterprise.setEntState(1);
        enterprise.setAuthState(1);
        baseMapper.insert(enterprise);

        log.info("更新用户与企业绑定关系");
        userService.lambdaUpdate().set(SysUser::getScopeId, enterprise.getId()).eq(SysUser::getUserId, SecurityUtils.getLoginUser().getUser().getUserId()).update();

        if (!CollectionUtil.isEmpty(entity.getAttachIds())) {
            log.info("更新附件绑定关系");
            attachService.lambdaUpdate().set(Attach::getAttachType, AttachTypeEnum.ENT)
                    .set(Attach::getDataId, enterprise.getId())
                    .in(Attach::getId, entity.getAttachIds()).update();
        }
        SecurityUtils.getLoginUser().getUser().setScopeId(enterprise.getId().toString());
        return true;
    }

    @Override
    public Page<Enterprise> selectEnterprise(Enterprise entity) {
        QueryWrapper<Enterprise> queryWrapper = new QueryWrapper<Enterprise>()
                .eq(!StrUtil.isEmpty(entity.getProvinceId()), "a.province_id", entity.getProvinceId())
                .eq(!StrUtil.isEmpty(entity.getCityId()), "a.city_id", entity.getCityId())
                .eq(!StrUtil.isEmpty(entity.getDistrictId()), "a.district_id", entity.getDistrictId())
                .like(!StrUtil.isEmpty(entity.getEntName()), "a.ent_name", entity.getEntName())
                .like(!StrUtil.isEmpty(entity.getLicense()), "a.license", entity.getLicense())
                .eq(entity.getEntState() != null, "a.ent_state", entity.getEntState())
                .eq(entity.getAuthState() != null, "a.auth_state", entity.getAuthState())
                .eq("b.user_type", UserTypeEnum.ENT_ADMIN)
                .orderByDesc("a.id");
        SysUser user = SecurityUtils.getLoginUser().getUser();
        switch (user.getUserType()) {
            case GOV_PROV:
                queryWrapper.eq("a.province_id", user.getScopeId());
                break;
            case GOV_CITY:
                queryWrapper.eq("a.city_id", user.getScopeId());
                break;
            case GOV_DISTRI:
                queryWrapper.eq("a.district_id", user.getScopeId());
                break;
            default:
                break;
        }

        Page<Enterprise> page = baseMapper.selectEnterprisePage(PageUtils.initPage(), queryWrapper);
        if (!CollectionUtil.isEmpty(page.getRecords())) {
            for (Enterprise e : page.getRecords()) {
                e.setProvinceName(regionService.getNameById(e.getProvinceId()));
                e.setCityName(regionService.getNameById(e.getCityId()));
                e.setDistrictName(regionService.getNameById(e.getDistrictId()));
            }
        }

        return page;
    }

    @Override
    public IndexRptVO rptEnterprise() {
        QueryWrapper<Enterprise> queryWrapper = new QueryWrapper<Enterprise>();

        SysUser user = SecurityUtils.getLoginUser().getUser();
        switch (user.getUserType()) {
            case ADMIN:
                break;
            case GOV_PROV:
                queryWrapper.eq("province_id", user.getScopeId());
                break;
            case GOV_CITY:
                queryWrapper.eq("city_id", user.getScopeId());
                break;
            case GOV_DISTRI:
                queryWrapper.eq("district_id", user.getScopeId());
                break;

            case ENT_ADMIN:
            case ENT_ADMIN_TECH:
            case ENT_ADMIN_FIN:
            case ENT_TECH:
            case ENT_FIN:
                queryWrapper.eq("id", user.getScopeId());
                break;

            default:
                break;
        }
        queryWrapper.eq("u.user_type", "ENT_ADMIN");
        return baseMapper.rptEnterprise(queryWrapper);
    }

    @Override
    public Boolean checkLicense(String license) {
        return this.lambdaQuery().eq(Enterprise::getLicense, license).exists();
    }

    @Override
    public Boolean modifyServiceTime(Enterprise enterprise) {
        if (enterprise.getStartDate().compareTo(enterprise.getEndDate()) > 0) {
            throw new ServiceException("服务开始时间不得小于结束时间");
        }

        EnterpriseLog log = new EnterpriseLog();
        Enterprise ori = this.getById(enterprise.getId());
        log.setOperName(SecurityUtils.getUsername());
        log.setEnterpriseId(ori.getId());
        String operMsg = "服务时间从[" + ori.getStartDate() + "-" + ori.getEndDate() + "]修改为[" + enterprise.getStartDate() + "-" + enterprise.getEndDate() + "]";
        log.setOperMsg(operMsg);
        enterpriseLogService.save(log);

        boolean expired = true;
        String now = DateUtil.formatDate(new Date());
        if (now.compareTo(enterprise.getStartDate()) >= 0 && now.compareTo(enterprise.getEndDate()) <= 0) {
            expired = false;
        }

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String nowDate = format.format(new Date());
        // 修改账户为正常
        if (nowDate.compareTo(enterprise.getEndDate()) > 0) {
            userService.lambdaUpdate().set(SysUser::getStatus, UserConstants.NORMAL).eq(SysUser::getScopeId, enterprise.getId()).update();
        }

        return this.lambdaUpdate()
                .set(Enterprise::getStartDate, enterprise.getStartDate())
                .set(Enterprise::getEndDate, enterprise.getEndDate())
                .set(!expired && ori.getEntState() == 3, Enterprise::getEntState, 2)    //已过期企业更新为服务中
                .eq(Enterprise::getId, enterprise.getId()).update();
    }

    @Override
    public Enterprise getById(Serializable id) {
        Enterprise e = baseMapper.selectById(id);
        e.setProvinceName(regionService.getNameById(e.getProvinceId()));
        e.setCityName(regionService.getNameById(e.getCityId()));
        e.setDistrictName(regionService.getNameById(e.getDistrictId()));
        return e;
    }
}
