package com.chinaweal.aiccs.aiccs.security.controller;

import com.alibaba.fastjson.JSONObject;
import com.chinaweal.aiccs.aiccs.security.entity.PenaltyAcceptLog;
import com.chinaweal.aiccs.aiccs.security.entity.PenaltyAppInfo;
import com.chinaweal.aiccs.aiccs.security.entity.PenaltyCaseInfo;
import com.chinaweal.aiccs.aiccs.security.entity.PenaltyEntInfo;
import com.chinaweal.aiccs.aiccs.security.entity.dto.LoginInfoParamDto;
import com.chinaweal.aiccs.aiccs.security.entity.dto.PenaltyCaseInfoEntInfoDto;
import com.chinaweal.aiccs.aiccs.security.entity.dto.PenaltyCaseInfoRequestDto;
import com.chinaweal.aiccs.aiccs.security.entity.vo.SecurityResultAcceptVO;
import com.chinaweal.aiccs.aiccs.security.entity.vo.SecurityResultVO;
import com.chinaweal.aiccs.aiccs.security.enums.ErrorCode;
import com.chinaweal.aiccs.aiccs.security.service.IPenaltyAcceptLogService;
import com.chinaweal.aiccs.aiccs.security.service.IPenaltyAppInfoService;
import com.chinaweal.aiccs.aiccs.security.service.IPenaltyCaseInfoService;
import com.chinaweal.aiccs.aiccs.security.service.IPenaltyEntInfoService;
import com.chinaweal.aiccs.common.constant.CommonConstants;
import com.chinaweal.aiccs.common.constant.Constant;
import com.chinaweal.aiccs.common.util.DateUtils;
import com.chinaweal.aiccs.common.util.StringUtils;
import com.chinaweal.aiccs.org.entity.TUsers;
import com.chinaweal.aiccs.org.service.TUsersService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 批量吊销对外接口
 *
 * @author lroyia
 * @since 2026/1/12 15:46
 **/
@Slf4j
@RestController
@RequestMapping("/security")
public class PenaltySecurityController {

    @Autowired
    private TUsersService tUsersService;
    @Autowired
    private IPenaltyAppInfoService penaltyAppInfoService;
    @Autowired
    private IPenaltyAcceptLogService penaltyAcceptLogService;
    @Autowired
    private IPenaltyCaseInfoService penaltyCaseInfoService;
    @Autowired
    private IPenaltyEntInfoService penaltyEntInfoService;

    /**
     * 登录
     *
     * @param paramDto 登录参数
     * @return 登录结果
     */
    @PostMapping("/login")
    public Object login(@RequestBody LoginInfoParamDto paramDto) {
        String appKey = paramDto.getAppKey();
        String appSecret = paramDto.getAppSecret();
        if (StringUtils.isBlank(appKey)) {
            return SecurityResultVO.error(ErrorCode.APP_KEY_INVALID);
        }
        if (StringUtils.isBlank(appSecret)) {
            return SecurityResultVO.error(ErrorCode.APP_SECRET_INVALID);
        }
        PenaltyAppInfo byId = penaltyAppInfoService.getById(appKey);
        if (byId == null) {
            return SecurityResultVO.error(ErrorCode.APP_KEY_INVALID);
        }
        if (StringUtils.notEquals(byId.getAppSecret(), appSecret)) {
            return SecurityResultVO.error(ErrorCode.APP_SECRET_INVALID);
        }
        if (StringUtils.isBlank(paramDto.getAccount())) {
            return SecurityResultVO.error(ErrorCode.LOGIN_INFO_INVALID);
        }
        TUsers one = tUsersService.lambdaQuery().eq(TUsers::getUsername, paramDto.getAccount())
                .eq(TUsers::getDeleted, Constant.FALSE_0_STR).eq(TUsers::getLocked, Constant.FALSE_0_STR).last("limit 1").one();
        if (one == null) {
            return SecurityResultVO.error(ErrorCode.LOGIN_INFO_INVALID);
        }
        JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(SecurityResultVO.success()));
        jsonObject.put("access_token", penaltyAppInfoService.generateAccessToken(byId, one));
        return jsonObject;
    }

    /**
     * 登出
     *
     * @param accessToken accessToken
     * @return 操作结果
     */
    @PostMapping("/logout")
    public SecurityResultVO logout(@RequestParam("access_token") String accessToken) {
        penaltyAppInfoService.removeAccessToken(accessToken);
        return SecurityResultVO.success();
    }

    /**
     * 批量吊销对外接口
     *
     * @param requestDto 请求参数
     * @return 请求结果
     */
    @PostMapping("receiveCaseInfo")
    public SecurityResultVO receiveCaseInfo(@RequestParam("access_token") String accessToken,
                                            @RequestBody PenaltyCaseInfoRequestDto requestDto) {
        if (!penaltyAppInfoService.existsAccessToken(accessToken)) {
            return SecurityResultVO.error(ErrorCode.ACCESS_TOKEN_INVALID);
        }
        if (StringUtils.isBlank(requestDto.getCaseid())) {
            return SecurityResultVO.error(ErrorCode.PARAM_VALID_FAIL_0);
        }
        if (StringUtils.isBlank(requestDto.getCasename())) {
            return SecurityResultVO.error(ErrorCode.PARAM_VALID_FAIL_1);
        }
        if (StringUtils.isBlank(requestDto.getCaseintroduction())) {
            return SecurityResultVO.error(ErrorCode.PARAM_VALID_FAIL_2);
        }
        if (StringUtils.isBlank(requestDto.getIllegality())) {
            return SecurityResultVO.error(ErrorCode.PARAM_VALID_FAIL_3);
        }
        if (StringUtils.isBlank(requestDto.getPenalty())) {
            return SecurityResultVO.error(ErrorCode.PARAM_VALID_FAIL_4);
        }
        if (StringUtils.isBlank(requestDto.getPenaltydate())) {
            return SecurityResultVO.error(ErrorCode.PARAM_VALID_FAIL_5);
        }
        if (StringUtils.isBlank(requestDto.getPenaltyorg())) {
            return SecurityResultVO.error(ErrorCode.PARAM_VALID_FAIL_6);
        }
        if (CollectionUtils.isEmpty(requestDto.getPenaltylist())) {
            return SecurityResultVO.error(ErrorCode.PARAM_VALID_FAIL_7);
        }
        for (PenaltyCaseInfoEntInfoDto each : requestDto.getPenaltylist()) {
            if (StringUtils.isAnyBlank(each.getPripid(), each.getUniscid(), each.getLegal(), each.getEnttype())) {
                return SecurityResultVO.error(ErrorCode.PARAM_VALID_FAIL_8);
            }
        }

        PenaltyAcceptLog penaltyAcceptLog = new PenaltyAcceptLog();
        penaltyAcceptLog.setAcceptId(StringUtils.getUUID());
        penaltyAcceptLog.setDataJson(JSONObject.toJSONString(requestDto));
        penaltyAcceptLog.setCreateTime(LocalDateTime.now());
        penaltyAcceptLogService.save(penaltyAcceptLog);

        // 保存案件信息到PENALTY_CASE_INFO表
        PenaltyCaseInfo penaltyCaseInfo = new PenaltyCaseInfo();
        penaltyCaseInfo.setCaseid(requestDto.getCaseid());
        penaltyCaseInfo.setAcceptid(penaltyAcceptLog.getAcceptId());
        penaltyCaseInfo.setCasename(requestDto.getCasename());
        penaltyCaseInfo.setCaseintroduction(requestDto.getCaseintroduction());
        penaltyCaseInfo.setIllegality(requestDto.getIllegality());
        penaltyCaseInfo.setPenalty(requestDto.getPenalty());
        penaltyCaseInfo.setPenaltydate(LocalDate.parse(requestDto.getPenaltydate(), DateTimeFormatter.ofPattern(DateUtils.DATE_DEFAULT_FORMAT)));
        penaltyCaseInfo.setPenaltyorg(requestDto.getPenaltyorg());
        penaltyCaseInfo.setUpdateTime(LocalDateTime.now());
        penaltyCaseInfo.setFlgDeleted(CommonConstants.FALSE_0);
        PenaltyCaseInfo byId = penaltyCaseInfoService.getById(penaltyCaseInfo.getCaseid());
        if (byId != null) {
            penaltyCaseInfoService.updateById(penaltyCaseInfo);
        } else {
            penaltyCaseInfo.setCreateTime(LocalDateTime.now());
            penaltyCaseInfoService.save(penaltyCaseInfo);
        }

        // 保存吊销主体清单到PENALTY_ENT_INFO表
        for (PenaltyCaseInfoEntInfoDto entInfoDto : requestDto.getPenaltylist()) {
            PenaltyEntInfo one = penaltyEntInfoService.lambdaQuery().eq(PenaltyEntInfo::getCaseid, requestDto.getCaseid())
                    .eq(PenaltyEntInfo::getPripid, entInfoDto.getPripid()).ne(PenaltyEntInfo::getFlgDeleted, CommonConstants.TRUE_1)
                    .last("limit 1").one();

            PenaltyEntInfo penaltyEntInfo = new PenaltyEntInfo();
            penaltyEntInfo.setCaseid(requestDto.getCaseid());
            penaltyEntInfo.setPripid(entInfoDto.getPripid());
            penaltyEntInfo.setUniscid(entInfoDto.getUniscid());
            penaltyEntInfo.setLegal(entInfoDto.getLegal());
            penaltyEntInfo.setEnttype(StringUtils.trimToEmpty(cleanEntTypeCode(entInfoDto.getEnttype())));
            penaltyEntInfo.setUpdateTime(LocalDateTime.now());
            penaltyEntInfo.setFlgDeleted("0");
            if (one == null) {
                penaltyEntInfo.setCreateTime(LocalDateTime.now());
                penaltyEntInfoService.save(penaltyEntInfo);
            } else {
                penaltyEntInfo.setId(one.getId());
                penaltyEntInfoService.updateById(penaltyEntInfo);
            }
        }

        return SecurityResultAcceptVO.success(penaltyAcceptLog.getAcceptId());
    }

    /**
     * 清洗市场主体类型编码
     * 从"类型中文名(类型编码)"格式中提取纯类型编码
     * 支持多个括号、中文括号和英文括号
     *
     * @param enttype 原始市场主体类型字符串
     * @return 清洗后的类型编码，如果无法提取则返回原字符串
     */
    private String cleanEntTypeCode(String enttype) {
        if (StringUtils.isBlank(enttype)) {
            return enttype;
        }

        String str = enttype.trim();

        // 替换中文括号为英文括号，统一处理
        str = str.replace('（', '(').replace('）', ')');

        // 找到最后一个左括号
        int lastLeftBracket = str.lastIndexOf('(');
        if (lastLeftBracket == -1) {
            // 没有找到括号，直接返回原字符串
            return str;
        }

        // 找到最后一个左括号对应的右括号
        int lastRightBracket = str.lastIndexOf(')');
        if (lastRightBracket == -1 || lastRightBracket < lastLeftBracket) {
            // 没有找到对应的右括号，直接返回原字符串
            return str;
        }

        // 提取括号内的内容
        String code = str.substring(lastLeftBracket + 1, lastRightBracket).trim();

        // 如果提取的内容为空，返回原字符串
        return StringUtils.isBlank(code) ? enttype : code;
    }
}
