package cn.api.atv;

import java.time.LocalDateTime;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.component.RedisKit;
import cn.constant.CommonConst;
import cn.logger.AsyncLoggingFactory;
import cn.orm.sqltoy.plus.query.LambdaQueryWrapper;
import cn.pojo.atv.system.SysLoginModel;
import cn.pojo.entity.TSysRolePerm;
import cn.pojo.entity.TSysUser;
import cn.schedule.core.AsyncManager;
import cn.service.token.JwtTokenService;
import cn.util.codec.EncryKit;
import cn.util.core.LogKit;
import cn.util.string.StringKit;
import com.alibaba.fastjson2.JSONObject;
import org.springframework.beans.BeanUtils;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import cn.facade.abs.IService;
import cn.common.annotation.Log;
import cn.common.enums.BizOpType;
import cn.common.enums.ResultCode;
import cn.orm.sqltoy.model.Page;
import cn.orm.sqltoy.plus.Wrappers;
import cn.orm.sqltoy.plus.query.QueryWrapper;
import cn.pojo.atv.AtvBoardCard;
import cn.pojo.atv.AtvBoardCardAgeing;
import cn.pojo.atv.AtvBoardCardTest;
import cn.pojo.atv.AtvBoardCardTestItem;
import cn.pojo.atv.vo.WinccBoardCardTestPage;
import cn.util.core.IsKit;
import cn.util.core.TypeKit;
import cn.util.time.TimeKit;
import cn.service.atv.Result;

import javax.annotation.Resource;

/**
 * 自动测试平台： 上位机-板卡老化表
 */
@RestController
@RequestMapping("/atv")
public class AtvWinCtrl extends IService {
    @Resource
    private JwtTokenService tokenService;
    @Resource
    private RedisKit redisUtil;

    /************上位机登录******/
    /**
     * public Result<JSONObject> winccLogin(@RequestBody Map<String,String> sysLoginModel)
     */
    @PostMapping(value = "/sys/winccLogin", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @Log(title = "板卡老化表-登录", businessType = BizOpType.SELECT)
    public Object winccLogin(@RequestBody SysLoginModel sysLoginModel) {
        LogKit.info("lhw/sys/winccLogin");
        String username = sysLoginModel.getUsername();
        String password = sysLoginModel.getPassword();

        //1. 校验用户是否有效
        QueryWrapper<TSysUser> wrapper = Wrappers.wrapper(TSysUser.class)
                .eq("userName", username);
        TSysUser entity = daoService.findOne(wrapper);
        //情况1：根据用户信息查询，该用户不存在
        if (IsKit.isNull(entity)) {
            AsyncManager.me().execute(AsyncLoggingFactory.insertLoginInfo(username, CommonConst.LOGIN_FAIL, "用户登录失败，用户不存在！"));
            return Result.error500("该用户不存在，请注册!");
        }
        //情况2：根据用户信息查询，该用户已注销
        if (CommonConst.CHAR_NUM_1.equals(entity.getDelFlag())) {
            AsyncManager.me().execute(AsyncLoggingFactory.insertLoginInfo(username, CommonConst.LOGIN_FAIL, "用户登录失败，用户已注销！"));
            return Result.error500("该用户已注销!");
        }
        //情况3：根据用户信息查询，该用户已冻结
        if (CommonConst.CHAR_NUM_1.equals(entity.getStatus())) {
            AsyncManager.me().execute(AsyncLoggingFactory.insertLoginInfo(username, CommonConst.LOGIN_FAIL, "用户登录失败，用户已冻结！"));
            return Result.error500("该用户已冻结!");
        }
        //2. 校验用户名或密码是否正确
        String sysPassword = entity.getPassword();
        Boolean pTest = EncryKit.matchesPassword(password, sysPassword);
        if (!pTest) {
            return Result.error500("用户名或密码错误");
        }

        //3. 校验用户名是否是上位机管理员 "/wincc"
        //in库表字符串含有:[]，即字段值类似：[1,2]
        String roleIds = StringKit.removeBracket(entity.getRoleIds());
        QueryWrapper<TSysRolePerm> wrapper1 = Wrappers.wrapper(TSysRolePerm.class)
                .select("component")
                .in("roleId", Arrays.asList(roleIds.split(",")));
        TSysRolePerm entityperm = daoService.findOne(wrapper1);
        if (IsKit.isNull(entityperm) || IsKit.isNull(entityperm.getComponent())) {
            return Result.error500("您不是上位机管理员");
        }
        if (!(entityperm.getComponent()).contains("*")
                && !(entityperm.getComponent()).contains("wincc")) {
            return Result.error500("您不是上位机管理员");
        }
        //4.校验用户所在部门信息
            /*
            Integer orgCode = entity.getDeptId();
            if (IsKit.isNullOrEmpty(orgCode)) {
                result.error500("用户暂未归属部门,不可登录!");
            }*/

        JSONObject obj = new JSONObject();
        //登录用户信息
        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("realname",entity.getNickName());
        userInfo.put("orgCode",entity.getDeptId());
        //obj.put("userInfo", entity);
        obj.put("userInfo", userInfo);

        //生成token sam
        String token = tokenService.appSign(username, sysPassword);
        // 设置超时时间
        redisUtil.set(CommonConst.PREFIX_USER_TOKEN + token, token);
        redisUtil.expire(CommonConst.PREFIX_USER_TOKEN + token, CommonConst.EXPIRE_TIME * 2 / 1000);
        System.out.println("W-2：" + token);
        //token 信息
        obj.put("token", token);

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("success", true);
        resultMap.put("code", 200);
        resultMap.put("result", obj);
        AsyncManager.me().execute(AsyncLoggingFactory.insertLoginInfo(username, CommonConst.LOGIN_SUCCESS, "用登录成功[上位机端]！"));
        System.out.println("W-1：" + resultMap);
        return resultMap;
    }


    /************上位机-板卡老化表******/
    @PostMapping(value = "/wincc/atvBoardCardAgeing/add")
    @Log(title = "板卡老化表-添加", businessType = BizOpType.DELETE)
    public Object boardCardAgeingInsert(@RequestBody AtvBoardCardAgeing atvBoardCardAgeing) {
        LogKit.info("lhw/wincc/atvBoardCardAgeing/add");
        QueryWrapper<AtvBoardCard> queryWrapper = Wrappers.wrapper(AtvBoardCard.class)
                .eq("sn", atvBoardCardAgeing.getBoardCardId());
        AtvBoardCard atvBoardCard = daoService.findOne(queryWrapper);
        if (IsKit.isNull(atvBoardCard)) {
            return Result.error("未找到板卡");
        }
        atvBoardCardAgeing.setBoardCardId(atvBoardCard.getId());
        atvBoardCardAgeing.setSubmitTime(TimeKit.getNowLocalDateTime());
        daoService.save(atvBoardCardAgeing);
        return Result.OK("添加成功！");
    }


    /************上位机-板卡测试表******/
    @PostMapping(value = "/wincc/atvBoardCardTest/add")
    @Log(title = "板卡测试表-添加", businessType = BizOpType.INSERT)
    public Object boardCardTestInsert(@RequestBody WinccBoardCardTestPage winccBoardCardTestPage) {
        LogKit.info("lhw/wincc/atvBoardCardTest/add");
        AtvBoardCardTest atvBoardCardTest = new AtvBoardCardTest();
        BeanUtils.copyProperties(winccBoardCardTestPage, atvBoardCardTest);
        LogKit.info("lhw/wincc/atvBoardCardTest/add/" + atvBoardCardTest.getId() + "/" + atvBoardCardTest.getBoardCardId());
        QueryWrapper<AtvBoardCard> queryWrapper = Wrappers.wrapper(AtvBoardCard.class)
                .eq("id", winccBoardCardTestPage.getBoardCardId());
        LogKit.info("lhw/wincc/atvBoardCardTest/add/winccBoardCardTestPage/" + winccBoardCardTestPage.getBoardCardId());
        AtvBoardCard atvBoardCard = daoService.findOne(queryWrapper);
        if (IsKit.isNull(atvBoardCard)) {
            return Result.error("未找到板卡");
        }
        atvBoardCardTest.setBoardCardId(atvBoardCard.getId());
        atvBoardCardTest.setLineId(atvBoardCard.getLineId());
        atvBoardCardTest.setId(atvBoardCard.getId());
        _saveMain(atvBoardCardTest, atvBoardCard.getBoardCardType().toString(), winccBoardCardTestPage.getAtvBoardCardTestItemList());
        return Result.OK("添加成功！");
    }
    /**
     * 获取 日期字符串
     */
    private String getDate() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyMMdd");
        return simpleDateFormat.format(new Date());
    }
    private String _boardCardType(String type) {
        return switch (type) {
            case "1" -> "DYB";
            case "2" -> "YPB";
            case "5" -> "GFB";
            case "3" -> "KZB";
            case "4" -> "CLB";
            default -> "DCU";
        };
    }
    /*入库单规则
 * 电源板 DYB+当前年月+000X（DYB2023020001）
   音频板  YPB+当前年月+000X（YPB2023020001）
   功放板GFB+当前年月+000X（GFB2023020001）
   控制板KZB+当前年月+000X（KZB2023020001）
   重连板CLB+当前年月+000X（CLB2023020001）
   DCU DCU+当前年月+000X（DCU2023020001）
 *  */
    private String makeSn(String boardCardId, String boardCardType)
    {
        String sn = "";
        //查询当天最后一条测试记录
        LambdaQueryWrapper<AtvBoardCardTest> wrapper = Wrappers.lambdaWrapper(AtvBoardCardTest.class)
                .eq(AtvBoardCardTest::getBoardCardId, boardCardId)
                .like(AtvBoardCardTest::getTestTime, TimeKit.getToday())
                .orderByDesc(AtvBoardCardTest::getTestTime);
        AtvBoardCardTest entity = daoService.findOne(wrapper);
        if (IsKit.isNullOrEmpty(entity)) {
            //生成第一张）
            sn = _boardCardType(boardCardType) + getDate() + "0001";
        } else {
            //生成下一个单据号
            sn = entity.getSn();
            sn = _boardCardType(boardCardType) + getDate() + String.format("%0" + sn.substring(9).length() + "d", Integer.parseInt(sn.substring(9)) + 1);
        }
        return sn;
    }

    private String makeSn2(String boardCardType)
    {
        String sn = _boardCardType(boardCardType);
        LambdaQueryWrapper<AtvBoardCard> wrapper = Wrappers.lambdaWrapper(AtvBoardCard.class)
                .like(AtvBoardCard::getSn, sn)
                .orderByDesc(AtvBoardCard::getSn);
        AtvBoardCard entity = daoService.findOne(wrapper);
        if (IsKit.isNullOrEmpty(entity)) {
            //生成第一张）
            sn = sn + "0001";
        } else {
            //生成下一个单据号
            String preSn = entity.getSn();
            sn = sn  + String.format("%0" + preSn.substring(3).length() + "d", Integer.parseInt(preSn.substring(3)) + 1);
        }
        return sn;
    }


    private Boolean _saveMain(AtvBoardCardTest
                                      atvBoardCardTest, String boardCardType, List<AtvBoardCardTestItem> atvBoardCardTestItemList) {

        LogKit.info("lhw/wincc/atvBoardCardTest/save:" + atvBoardCardTest);
        //2023.29 添加 板卡编号 board_card_id
        atvBoardCardTest.setSn(makeSn(atvBoardCardTest.getBoardCardId(), boardCardType));
        if(IsKit.isNullOrEmpty(atvBoardCardTest.getTestTime())){
            atvBoardCardTest.setTestTime(LocalDateTime.now());
        }

        LogKit.info("lhw/wincc/atvBoardCardTest/save2:" + atvBoardCardTest);
        Object obj = daoService.saveOrUpdate(atvBoardCardTest);
        if (IsKit.isNotNullOrEmpty(atvBoardCardTestItemList)) {
            for (AtvBoardCardTestItem entity : atvBoardCardTestItemList) {
                //外键设置
                entity.setBoardCardTestId(atvBoardCardTest.getId());
                daoService.save(entity);
            }
        }
        return IsKit.isNotNull(obj);
    }

    /************上位机-板卡表******/
    @PostMapping(value = "/wincc/atvBoardCard/add")
    @Log(title = "板卡表-添加", businessType = BizOpType.UPDATEINSERT)
    public Object boardCardInsertUpdate(@RequestBody AtvBoardCard atvBoardCard) {
        LogKit.info("lhw/wincc/atvBoardCard/add");
        atvBoardCard.setId(atvBoardCard.getSn());
        QueryWrapper<AtvBoardCard> queryWrapper = Wrappers.wrapper(AtvBoardCard.class)
                .eq("id", atvBoardCard.getId());
        LogKit.info("lhw/wincc/atvBoardCard/add/sn" + atvBoardCard.getSn());
        LogKit.info("lhw/wincc/atvBoardCard/add/id" + atvBoardCard.getId());
        AtvBoardCard atvBoardCardOld = daoService.findOne(queryWrapper);

       /*AtvItem项目列表,新版中不需要
        * 问题：国家、城市、线路需要改为从页面或其他地方直接写入atvBoardCard
        QueryWrapper<AtvItem> queryWrapper2 = Wrappers.wrapper(AtvItem.class)
				.eq("id", atvBoardCard.getItemId());
        AtvItem atvItem = daoService.findOne(queryWrapper2);
        */
        //更新
        if (IsKit.isNotNull(atvBoardCardOld)) {
            LogKit.info("lhw/wincc/atvBoardCard/add/notnull");
            /*if (atvItem != null) {
                atvBoardCardOld.setItemId(atvBoardCard.getItemId());
                atvBoardCardOld.setCountryId(atvItem.getCountryId());
                atvBoardCardOld.setAreaId(atvItem.getAreaId());
                atvBoardCardOld.setLineId(atvItem.getLineId());
            }*/
            atvBoardCardOld.setBoardCardType(atvBoardCard.getBoardCardType());
            atvBoardCardOld.setCarriageId(atvBoardCard.getCarriageId());
            atvBoardCardOld.setEquipmentId(atvBoardCard.getEquipmentId());
            atvBoardCardOld.setTestTime(atvBoardCard.getTestTime());
            atvBoardCardOld.setTrainId(atvBoardCard.getTrainId());
            atvBoardCardOld.setWorkingHours(atvBoardCard.getWorkingHours());
            daoService.update(atvBoardCardOld);
        }
        //新增
        else {
            /*if (atvItem != null) {
                atvBoardCard.setCountryId(atvItem.getCountryId());
                atvBoardCard.setAreaId(atvItem.getAreaId());
                atvBoardCard.setLineId(atvItem.getLineId());
            }*/
            LogKit.info("lhw/wincc/atvBoardCard/add/null/" + atvBoardCard.getSn() + "/" + atvBoardCard.getId());
            atvBoardCard.setSn(makeSn2(atvBoardCard.getBoardCardType().toString()));
            daoService.save(atvBoardCard);
        }
        return Result.OK("添加成功！");
    }

    /************上位机-项目表：：新版本：无atvItem*/
    @GetMapping(value = "/wincc/atvItem/list")
    @Log(title = "项目表-分页列表查询", businessType = BizOpType.DELETE)
    public Object queryPageList(@RequestParam Map<String, Object> paramMap) {
        LogKit.info("lhw/wincc/atvItem/list");
        LogKit.info("lhw" + paramMap.toString());
        Page<?> pageResult;
        try {
            pageResult = daoService.getPage("atv_item", paramMap);
            if (IsKit.isNullOrEmpty(pageResult)) {
                LogKit.info("lhw/wincc/atvItem/list/SQL_RUN_1");
                return Result.error(ResultCode.SQL_RUN.getMsg());
            }
            List<Map<String, Object>> resultList = TypeKit.cast(pageResult.getRows());
            return Result.OK(resultList);
        } catch (Exception e) {
            LogKit.info("lhw/wincc/atvItem/list/SQL_RUN_2");
            return Result.error(ResultCode.SQL_RUN.getMsg());
        }
    }
}
