package shop.alien.store.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import shop.alien.entity.store.StoreImg;
import shop.alien.entity.store.StoreInfo;
import shop.alien.entity.storePlatform.StoreLicenseHistory;
import shop.alien.mapper.StoreImgMapper;
import shop.alien.mapper.StoreInfoMapper;
import shop.alien.mapper.storePlantform.StoreLicenseHistoryMapper;
import shop.alien.store.util.ai.AiAuthTokenUtil;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;

/**
 * 证照审核异步服务
 * 用于异步处理证照审核，避免阻塞主流程
 *
 * @author system
 * @since 2026-01-14
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class LicenseAuditAsyncService {

    private final AiAuthTokenUtil aiAuthTokenUtil;
    private final RestTemplate restTemplate;
    private final StoreInfoMapper storeInfoMapper;
    private final StoreLicenseHistoryMapper licenseHistoryMapper;
    private final StoreImgMapper storeImgMapper;

    @Value("${third-party-license-review.base-url}")
    private String licenseReviewPath;

    /**
     * 异步调用证照审核AI接口并处理审核结果
     * 1. 调用AI接口获取审核结果
     * 2. 如果是营业执照（licenseStatus=1），解析并存入到期时间
     * 3. 根据审核结果（is_expired或is_valid）更新store_license_history表的审核状态
     *
     * @param storeId 门店ID
     * @param licenseStatus 证照类型：1-营业执照，2-其他资质证明
     * @param imageUrl 证照图片URL
     */
    @Async("taskExecutor")
    public void validateLicenseExpiryAndUpdate(Integer storeId, Integer licenseStatus, String imageUrl) {
        if (storeId == null || licenseStatus == null || StringUtils.isEmpty(imageUrl)) {
            log.warn("证照审核参数不完整，storeId={}, licenseStatus={}, imageUrl={}", storeId, licenseStatus, imageUrl);
            return;
        }

        try {
            String accessToken = aiAuthTokenUtil.getAccessToken();
            if (StringUtils.isEmpty(accessToken)) {
                log.error("获取AI访问令牌失败，门店ID：{}", storeId);
                return;
            }

            HttpHeaders aiHeaders = new HttpHeaders();
            aiHeaders.setContentType(MediaType.APPLICATION_JSON);
            aiHeaders.set("Authorization", "Bearer " + accessToken);

            // 构建请求体
            Map<String, Object> jsonBody = new HashMap<>();
            jsonBody.put("image_url", imageUrl);

            HttpEntity<Map<String, Object>> request = new HttpEntity<>(jsonBody, aiHeaders);

            // 设置超时时间
            HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
            factory.setConnectTimeout(10000); // 连接超时10秒
            factory.setReadTimeout(120000); // 读取超时120秒（2分钟）
            restTemplate.setRequestFactory(factory);

            ResponseEntity<String> response = restTemplate.postForEntity(licenseReviewPath, request, String.class);

            if (response.getStatusCodeValue() != 200) {
                log.error("证照审核接口调用失败，门店ID：{}，http状态：{}", storeId, response.getStatusCode());
                return;
            }

            if (StringUtils.isEmpty(response.getBody())) {
                log.error("证照审核接口返回内容为空，门店ID：{}", storeId);
                return;
            }

            JSONObject responseNode = JSONObject.parseObject(response.getBody());
            if (responseNode == null) {
                log.error("证照审核接口响应解析失败，门店ID：{}", storeId);
                return;
            }

            Integer code = responseNode.getInteger("code");
            if (code == null || code != 200) {
                String message = responseNode.getString("message");
                log.error("证照审核接口调用失败，门店ID：{}，错误码: {}, 错误信息: {}", storeId, code, message);
                return;
            }

            Map<String, Object> dataMap = (Map<String, Object>) responseNode.get("data");
            if (dataMap == null) {
                log.warn("证照审核接口返回data为空，门店ID：{}", storeId);
                return;
            }

            Boolean isValid = (Boolean) dataMap.get("is_valid");
            String expiryDateStr = (String) dataMap.get("expiry_date");
            Boolean isExpired = (Boolean) dataMap.get("is_expired");
            Integer remainingDays = (Integer) dataMap.get("remaining_days");
            String reason = (String) dataMap.get("reason");
            String licenseType = (String) dataMap.get("license_type");
            String auditTime = (String) dataMap.get("audit_time");
            Date reviewDate = Date.from(LocalDateTime.parse(auditTime).atZone(ZoneId.systemDefault()).toInstant());

            String licenseTypeName = licenseStatus == 1 ? "营业执照" : "其他资质证明";
            log.info("{}证照审核结果，门店ID：{}，图片URL：{}，is_valid={}，expiry_date={}，is_expired={}，remaining_days={}，license_type={}",
                    licenseTypeName, storeId, imageUrl, isValid, expiryDateStr, isExpired, remainingDays, licenseType);

            // 判断审核结果
            boolean needReject = false;
            boolean needApprove = false;
            String rejectReason = null;

            if (licenseStatus == 1) {
                List<String> licenseTypes = Arrays.asList("business_license", "legal_person_business_license");
                // 营业执照的审核逻辑
                if (!licenseTypes.contains(licenseType)) {
                    // 上传的图片不是营业执照
                    needReject = true;
                    rejectReason = "上传的图片不是营业执照";
                } else if (Boolean.TRUE.equals(isExpired)) {
                    // 营业执照已过期
                    needReject = true;
                    rejectReason = "已过期";
                } else if (Boolean.TRUE.equals(isValid) && licenseTypes.contains(licenseType) && Boolean.FALSE.equals(isExpired)) {
                    // 营业执照有效且未过期，审核通过
                    needApprove = true;
                }
            } else if (licenseStatus == 2) {
                // 其他资质证明的审核逻辑
                if (Boolean.FALSE.equals(isValid)) {
                    // 上传的不是证件图片
                    needReject = true;
                    rejectReason = "上传的图片含非证件图片";
                } else if (Boolean.TRUE.equals(isValid)) {
                    // 证件有效，审核通过
                    needApprove = true;
                }
            }

            // 更新store_license_history表的审核状态
            if (licenseStatus == 2) {
                // 其他资质证明：img_url字段包含多个URL（用逗号分隔），需要查找包含当前图片URL的记录
                LambdaUpdateWrapper<StoreLicenseHistory> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(StoreLicenseHistory::getStoreId, storeId)
                        .eq(StoreLicenseHistory::getLicenseStatus, licenseStatus)
                        .eq(StoreLicenseHistory::getLicenseExecuteStatus, 2) // 2-审核中
                        .like(StoreLicenseHistory::getImgUrl, imageUrl) // 使用like查找包含该图片URL的记录
                        .eq(StoreLicenseHistory::getDeleteFlag, 0);

                if (needReject) {
                    // 审核拒绝：一张图片审核拒绝或失败就设置状态为审核拒绝
                    updateWrapper.set(StoreLicenseHistory::getLicenseExecuteStatus, 3) // 3-审核拒绝
                            .set(StoreLicenseHistory::getReasonRefusal, rejectReason);
                    licenseHistoryMapper.update(null, updateWrapper);
                    log.info("{}AI审核拒绝，门店ID：{}，图片URL：{}，拒绝原因：{}", licenseTypeName, storeId, imageUrl, rejectReason);
                    
                    // 审核拒绝时，删除store_img表中的记录（逻辑删除），避免前端展示审核拒绝的图片
                    LambdaUpdateWrapper<StoreImg> deleteImgWrapper = new LambdaUpdateWrapper<>();
                    deleteImgWrapper.eq(StoreImg::getStoreId, storeId)
                            .eq(StoreImg::getImgType, 35) // 其他资质证明对应35
                            .eq(StoreImg::getImgUrl, imageUrl)
                            .eq(StoreImg::getDeleteFlag, 0)
                            .set(StoreImg::getDeleteFlag, 1);
                    storeImgMapper.update(null, deleteImgWrapper);
                    log.info("{}AI审核拒绝，已删除store_img记录，门店ID：{}，图片URL：{}", licenseTypeName, storeId, imageUrl);
                } else if (needApprove) {
                    // 审核通过：需要检查所有图片是否都审核通过
                    // 先查询当前记录，获取所有图片URL（查询状态为2或1的记录，因为第一张图片审核通过后状态会变为1）
                    StoreLicenseHistory currentHistory = licenseHistoryMapper.selectOne(
                            new LambdaQueryWrapper<StoreLicenseHistory>()
                                    .eq(StoreLicenseHistory::getStoreId, storeId)
                                    .eq(StoreLicenseHistory::getLicenseStatus, licenseStatus)
                                    .in(StoreLicenseHistory::getLicenseExecuteStatus, 1, 2) // 查询状态为1或2的记录
                                    .like(StoreLicenseHistory::getImgUrl, imageUrl)
                                    .eq(StoreLicenseHistory::getDeleteFlag, 0)
                                    .orderByDesc(StoreLicenseHistory::getCreatedTime) // 按创建时间倒序，获取最新的记录
                                    .last("LIMIT 1")
                    );
                    
                    if (currentHistory != null && StringUtils.isNotEmpty(currentHistory.getImgUrl())) {
                        // 如果状态还是2（审核中），更新为1（审核通过）
                        if (currentHistory.getLicenseExecuteStatus() == 2) {
                            updateWrapper.set(StoreLicenseHistory::getLicenseExecuteStatus, 1); // 1-审核通过
                            licenseHistoryMapper.update(null, updateWrapper);
                        }
                        log.info("{}AI审核通过，门店ID：{}，图片URL：{}", licenseTypeName, storeId, imageUrl);
                        
                        // 审核通过后，先清除旧的其他资质证明图片（不在当前批次中的）
                        String[] currentBatchUrls = currentHistory.getImgUrl().split(",");
                        LambdaUpdateWrapper<StoreImg> cleanOldWrapper = new LambdaUpdateWrapper<>();
                        cleanOldWrapper.eq(StoreImg::getStoreId, storeId)
                                .eq(StoreImg::getImgType, 35)
                                .eq(StoreImg::getDeleteFlag, 0)
                                .notIn(StoreImg::getImgUrl, Arrays.asList(currentBatchUrls))
                                .set(StoreImg::getDeleteFlag, 1);
                        storeImgMapper.update(null, cleanOldWrapper);
                        log.info("其他资质证明审核通过，已清除旧图片，门店ID：{}", storeId);
                        
                        // 审核通过后，插入store_img表（检查是否已存在，避免重复插入）
                        StoreImg existingImg = storeImgMapper.selectOne(
                                new LambdaQueryWrapper<StoreImg>()
                                        .eq(StoreImg::getStoreId, storeId)
                                        .eq(StoreImg::getImgType, 35)
                                        .eq(StoreImg::getImgUrl, imageUrl)
                                        .eq(StoreImg::getDeleteFlag, 0)
                        );
                        if (existingImg == null) {
                            // 根据imgUrl在allImgUrls中的位置确定imgSort
                            String[] allImgUrls = currentHistory.getImgUrl().split(",");
                            int imgSort = 1;
                            for (int i = 0; i < allImgUrls.length; i++) {
                                if (allImgUrls[i].equals(imageUrl)) {
                                    imgSort = i + 1;
                                    break;
                                }
                            }
                            
                            StoreImg storeImg = new StoreImg();
                            storeImg.setStoreId(storeId);
                            storeImg.setImgType(35); // 其他资质证明对应35
                            storeImg.setImgDescription("其他资质证明");
                            storeImg.setImgSort(imgSort);
                            storeImg.setImgUrl(imageUrl);
                            storeImg.setDeleteFlag(0);
                            storeImgMapper.insert(storeImg);
                            log.info("其他资质证明审核通过，已插入store_img表，门店ID：{}，图片URL：{}，排序：{}", storeId, imageUrl, imgSort);
                        } else {
                            log.info("其他资质证明审核通过，store_img表已存在该记录，门店ID：{}，图片URL：{}", storeId, imageUrl);
                        }
                    }
                }
            } else {
                // 营业执照：精确匹配imgUrl
                LambdaUpdateWrapper<StoreLicenseHistory> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(StoreLicenseHistory::getStoreId, storeId)
                        .eq(StoreLicenseHistory::getLicenseStatus, licenseStatus)
                        .eq(StoreLicenseHistory::getLicenseExecuteStatus, 2) // 2-审核中
                        .eq(StoreLicenseHistory::getImgUrl, imageUrl)
                        .eq(StoreLicenseHistory::getDeleteFlag, 0);

                if (needReject) {
                    // 审核拒绝
                    updateWrapper.set(StoreLicenseHistory::getLicenseExecuteStatus, 3) // 3-审核拒绝
                            .set(StoreLicenseHistory::getReasonRefusal, rejectReason);
                    licenseHistoryMapper.update(null, updateWrapper);
                    log.info("{}AI审核拒绝，门店ID：{}，图片URL：{}，拒绝原因：{}", licenseTypeName, storeId, imageUrl, rejectReason);
                    storeInfoMapper.update(null, new LambdaUpdateWrapper<StoreInfo>()
                            .eq(StoreInfo::getId, storeId)
                            .set(StoreInfo::getBusinessLicenseStatus, 3)
                            .set(StoreInfo::getReviewDate, reviewDate)
                            .set(StoreInfo::getBusinessLicenseReason, rejectReason)
                    );
                    // 审核拒绝时，不需要操作store_img表
                    // 因为uploadBusinessLicense方法不会插入新图片到store_img，旧的营业执照图片仍然有效
                    log.info("{}AI审核拒绝，保留原有营业执照图片不变，门店ID：{}，图片URL：{}", licenseTypeName, storeId, imageUrl);
                } else if (needApprove) {
                    // 审核通过
                    updateWrapper.set(StoreLicenseHistory::getLicenseExecuteStatus, 1); // 1-审核通过
                    licenseHistoryMapper.update(null, updateWrapper);
                    log.info("{}AI审核通过，门店ID：{}，图片URL：{}", licenseTypeName, storeId, imageUrl);
                    storeInfoMapper.update(null, new LambdaUpdateWrapper<StoreInfo>()
                            .eq(StoreInfo::getId, storeId)
                            .set(StoreInfo::getBusinessLicenseStatus, 1)
                            .set(StoreInfo::getReviewDate,reviewDate)
                            .set(StoreInfo::getUpdateBusinessLicenseTime, new Date())
                    );

                    // 审核通过后，解析并存入营业执照到期时间
                    if (StringUtils.isNotEmpty(expiryDateStr)) {
                        try {
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                            Date expiryDate = sdf.parse(expiryDateStr);

                            StoreInfo updateStoreInfo = new StoreInfo();
                            updateStoreInfo.setId(storeId);
                            updateStoreInfo.setBusinessLicenseExpirationTime(expiryDate);

                            // 同步更新门店到期时间（expirationTime）
                            // 门店到期时间 = min(合同到期时间, 营业执照到期时间)
                            // 由于合同到期时间未单独存储，需要根据旧值推断
                            StoreInfo currentStore = storeInfoMapper.selectById(storeId);
                            if (currentStore != null) {
                                Date currentExpiration = currentStore.getExpirationTime();
                                Date oldBizExpiration = currentStore.getBusinessLicenseExpirationTime();
                                if (currentExpiration != null && oldBizExpiration != null
                                        && currentExpiration.before(oldBizExpiration)) {
                                    // 合同到期时间 < 旧营业执照到期时间，说明合同是瓶颈
                                    // 新的门店到期时间 = min(合同到期时间, 新营业执照到期时间)
                                    updateStoreInfo.setExpirationTime(
                                            expiryDate.before(currentExpiration) ? expiryDate : currentExpiration
                                    );
                                } else {
                                    // 营业执照是瓶颈（或两者相等、或旧值为空）
                                    // 直接用新的营业执照到期时间更新
                                    updateStoreInfo.setExpirationTime(expiryDate);
                                }
                            } else {
                                updateStoreInfo.setExpirationTime(expiryDate);
                            }

                            storeInfoMapper.updateById(updateStoreInfo);
                            log.info("营业执照到期时间已更新，门店ID：{}，营业执照到期：{}，门店到期：{}",
                                    storeId, expiryDateStr, updateStoreInfo.getExpirationTime());
                        } catch (Exception e) {
                            log.error("解析营业执照到期时间失败，门店ID：{}，expiryDate：{}", storeId, expiryDateStr, e);
                        }
                    }

                    // 审核通过后，先逻辑删除旧的营业执照记录
                    LambdaUpdateWrapper<StoreImg> deleteOldImgWrapper = new LambdaUpdateWrapper<>();
                    deleteOldImgWrapper.eq(StoreImg::getStoreId, storeId)
                            .eq(StoreImg::getImgType, 14)
                            .eq(StoreImg::getDeleteFlag, 0)
                            .set(StoreImg::getDeleteFlag, 1);
                    storeImgMapper.update(null, deleteOldImgWrapper);

                    // 审核通过后，插入store_img表（检查是否已存在，避免重复插入）
                    StoreImg existingImg = storeImgMapper.selectOne(
                            new LambdaQueryWrapper<StoreImg>()
                                    .eq(StoreImg::getStoreId, storeId)
                                    .eq(StoreImg::getImgType, 14)
                                    .eq(StoreImg::getImgUrl, imageUrl)
                                    .eq(StoreImg::getDeleteFlag, 0)
                    );
                    if (existingImg == null) {
                        StoreImg storeImg = new StoreImg();
                        storeImg.setStoreId(storeId);
                        storeImg.setImgType(14); // 营业执照对应14
                        storeImg.setImgDescription("营业执照");
                        storeImg.setImgSort(0);
                        storeImg.setImgUrl(imageUrl);
                        storeImg.setDeleteFlag(0);
                        storeImgMapper.insert(storeImg);
                        log.info("营业执照审核通过，已插入store_img表，门店ID：{}，图片URL：{}", storeId, imageUrl);
                    } else {
                        log.info("营业执照审核通过，store_img表已存在该记录，门店ID：{}，图片URL：{}", storeId, imageUrl);
                    }
                }
            }
        } catch (Exception e) {
            String licenseTypeName = licenseStatus == 1 ? "营业执照" : "其他资质证明";
            log.error("调用{}证照审核接口异常，门店ID：{}，图片URL：{}", licenseTypeName, storeId, imageUrl, e);
            // AI审核失败不影响业务流程，继续执行
        }
    }
}

