package com.changhu.module.management.enums.handler;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.changhu.common.db.enums.*;
import com.changhu.common.enums.ResultCode;
import com.changhu.common.exception.MessageException;
import com.changhu.common.utils.UserUtil;
import com.changhu.module.management.pojo.entity.ManagementPoliceUnitUser;
import com.changhu.module.management.pojo.entity.PoliceUnit;
import com.changhu.module.management.pojo.vo.UnitCheckStatusVo;
import com.changhu.module.management.service.ManagementPoliceUnitUserService;
import com.changhu.module.management.service.PoliceUnitService;
import com.changhu.module.miniProgram.pojo.entity.MiniProgramUser;
import com.changhu.module.miniProgram.service.MiniProgramUserService;
import com.changhu.support.mybatisplus.pojo.entity.BaseEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.util.List;


/**
 * @author 20252
 * @createTime 2024/9/2 上午11:03
 * @desc PoliceUnitTypeHandler...
 */
@Slf4j
public class PoliceUnitTypeHandler extends AbstractUnitTypeHandler {

    private final PoliceUnitService policeUnitService = SpringUtil.getBean(PoliceUnitService.class);

    private final ManagementPoliceUnitUserService policeUnitUserService = SpringUtil.getBean(ManagementPoliceUnitUserService.class);

    private final MiniProgramUserService miniProgramUserService = SpringUtil.getBean(MiniProgramUserService.class);

    @Override
    public void pass(Long checkDataId) {
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        TransactionStatus status = transactionManager.getTransaction(def);

        try {
            PoliceUnit policeUnit = policeUnitService.getOptById(checkDataId).orElseThrow(() -> new MessageException(ResultCode.DATA_NOT_FOUND));
            //更新状态
            boolean update = policeUnitService.lambdaUpdate()
                    .set(PoliceUnit::getCheckStatus, CheckStatus.checked)
                    .eq(BaseEntity::getSnowFlakeId, checkDataId)
                    .update();
            if (!update) {
                throw new MessageException(ResultCode.ERROR);
            }
            //生成管理员账号密码
            String passWordEncrypt = UserUtil.passWordEncrypt(UserUtil.DEFAULT_PASSWORD);
            List<String> saltAndPassWord = StrUtil.split(passWordEncrypt, "$$");

            ManagementPoliceUnitUser managementPoliceUnitUser = new ManagementPoliceUnitUser();
            managementPoliceUnitUser.setPoliceUnitId(policeUnit.getSnowFlakeId());
            managementPoliceUnitUser.setName("超级管理员");
            managementPoliceUnitUser.setSex(Sex.UNKNOWN);
            managementPoliceUnitUser.setAccount(RandomUtil.randomString(6));
            managementPoliceUnitUser.setTelephone("");
            managementPoliceUnitUser.setSalt(saltAndPassWord.get(0));
            managementPoliceUnitUser.setPassword(saltAndPassWord.get(1));
            managementPoliceUnitUser.setIsAdmin(IsOrNot.IS);

            boolean save = policeUnitUserService.save(managementPoliceUnitUser);
            if (!save) {
                throw new MessageException(ResultCode.ERROR);
            }

            //提交事务
            transactionManager.commit(status);
        } catch (Exception e) {
            //回滚事务
            transactionManager.rollback(status);
            log.error("公安单位审核通过错误:{}", e.getMessage());
            throw new MessageException(e.getMessage());
        }
    }

    @Override
    public UnitCheckStatusVo getCheckStatus(String onlyCode) {
        PoliceUnit policeUnit = policeUnitService.lambdaQuery()
                .eq(PoliceUnit::getCode, onlyCode)
                .oneOpt()
                .orElseThrow(() -> new MessageException(ResultCode.DATA_NOT_FOUND));

        UnitCheckStatusVo unitCheckStatusVo = new UnitCheckStatusVo();
        unitCheckStatusVo.setCheckStatus(policeUnit.getCheckStatus());

        if (policeUnit.getCheckStatus().equals(CheckStatus.checked)) {
            ManagementPoliceUnitUser managementPoliceUnitUser = policeUnitUserService.lambdaQuery()
                    .eq(ManagementPoliceUnitUser::getPoliceUnitId, policeUnit.getSnowFlakeId())
                    .eq(ManagementPoliceUnitUser::getIsAdmin, IsOrNot.IS)
                    .oneOpt()
                    .orElseThrow(() -> new MessageException("超管账号未初始化 请联系管理员"));
            unitCheckStatusVo.setAccount(managementPoliceUnitUser.getAccount());
            unitCheckStatusVo.setRemark("恭喜!单位审核通过了,请使用管理员账号前往登录页进行登录.");
        } else {
            unitCheckStatusVo.setPassword(null);
            unitCheckStatusVo.setRemark("单位注册申请正在审核中...");
        }
        return unitCheckStatusVo;
    }

    @Override
    public void disableOrEnable(Long unitId) {
        PoliceUnit policeUnit = policeUnitService.lambdaQuery()
                .eq(BaseEntity::getSnowFlakeId, unitId)
                .oneOpt()
                .orElseThrow(() -> new MessageException(ResultCode.DATA_NOT_FOUND));
        //取反
        IsEnable isEnable = switch (policeUnit.getIsEnable()) {
            case TRUE -> IsEnable.FALSE;
            case FALSE -> IsEnable.TRUE;
        };

        boolean update = policeUnitService.lambdaUpdate()
                .set(PoliceUnit::getIsEnable, isEnable)
                .eq(BaseEntity::getSnowFlakeId, unitId)
                .update();
        if (!update) {
            throw new MessageException();
        }
    }

    @Override
    public void passMiniProgramUser(Long miniProgramUserId) {
        boolean update = miniProgramUserService.lambdaUpdate()
                .set(MiniProgramUser::getCheckStatus, CheckStatus.checked)
                .eq(BaseEntity::getSnowFlakeId, miniProgramUserId)
                .eq(MiniProgramUser::getIdentity, MiniProgramUserIdentity.POLICE)
                .update();
        if (!update) {
            throw new MessageException();
        }
    }

    @Override
    public void disableOrEnableMiniProgramUser(Long miniProgramUserId) {
        MiniProgramUser miniProgramUser = miniProgramUserService.lambdaQuery()
                .eq(BaseEntity::getSnowFlakeId, miniProgramUserId)
                .eq(MiniProgramUser::getIdentity, MiniProgramUserIdentity.POLICE)
                .oneOpt()
                .orElseThrow(() -> new MessageException(ResultCode.DATA_NOT_FOUND));

        //取反
        IsEnable isEnable = switch (miniProgramUser.getIsEnable()) {
            case TRUE -> IsEnable.FALSE;
            case FALSE -> IsEnable.TRUE;
        };

        boolean update = miniProgramUserService.lambdaUpdate()
                .set(MiniProgramUser::getIsEnable, isEnable)
                .eq(BaseEntity::getSnowFlakeId, miniProgramUserId)
                .update();
        if (!update) {
            throw new MessageException();
        }
    }
}
