package shop.alien.store.controller;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import shop.alien.entity.result.R;
import shop.alien.entity.store.StoreImg;
import shop.alien.entity.store.StoreOfficialAlbum;
import shop.alien.entity.store.vo.StoreImgInfoVo;
import shop.alien.entity.store.vo.StoreImgTypeVo;
import shop.alien.store.service.StoreImgService;
import shop.alien.store.service.StoreInfoService;
import shop.alien.store.service.StoreOfficialAlbumService;
import shop.alien.store.util.GroupConstant;
import shop.alien.store.util.ai.AiContentModerationUtil;

import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Qualifier;

/**
 * 二期-门店图片Controller
 *
 * @author ssk
 * @since 2024-12-05
 */
@Slf4j
@Api(tags = {"二期-门店图片"})
@ApiSort(5)
@CrossOrigin
@RestController
@RequestMapping("/img")
@RequiredArgsConstructor
public class StoreImgController {
    private final StoreImgService storeImgService;
    private final StoreInfoService storeInfoService;
    private final StoreOfficialAlbumService storeOfficialAlbumService;
    @Qualifier("imgAuditExecutor")
    private final ExecutorService imgAuditExecutor;

    @ApiOperation("获取图片")
    @ApiOperationSupport(order = 1)
    @ApiImplicitParams({@ApiImplicitParam(name = "storeId", value = "门店id", dataType = "Integer", paramType = "query", required = true),
            @ApiImplicitParam(name = "imgType", value = "图片类型, 0:其他, 1:入口图, 2:相册, 3:菜品, 4:环境, 5:价目表, 6:推荐菜, 7:菜单, 8:用户评论, 9:商家申诉, 10:商家头像, 11:店铺轮播图", dataType = "Integer", paramType = "query", required = true)})
    @GetMapping("/getByStoreId")
    public R<List<StoreImg>> getByStoreId(Integer storeId, Integer imgType) {
        log.info("StoreImgController.getByStoreId?storeId={}&imgType={}", storeId, imgType);
        return R.data(storeImgService.getStoreImg(storeId, imgType));
    }

    @ApiOperation("获取所有图片类型和数量")
    @ApiOperationSupport(order = 2)
    @ApiImplicitParams({@ApiImplicitParam(name = "storeId", value = "门店id", dataType = "Integer", paramType = "query", required = true)})
    @GetMapping("/getStoreImgTypeCount")
    public R<List<StoreImgTypeVo>> getStoreImgTypeCount(Integer storeId) {
        log.info("StoreImgController.getStoreImgTypeCount?storeId={}", storeId);
        return R.data(storeImgService.getStoreImgTypeCount(storeId));
    }

    @ApiOperation("新增或修改图片")
    @ApiOperationSupport(order = 3)
    @PostMapping("/saveOrUpdate")
    public R<String> saveOrUpdate(@RequestBody List<StoreImg> storeImgList) {
        log.info("StoreImgController.saveOrUpdate?storeImgList={}", storeImgList);
        Integer id = storeImgList.get(0).getId();
        if (storeImgService.saveOrUpdateBatch(storeImgList)) {
            if (null != id) {
                return R.success("修改成功");
            }
            return R.success("新增成功");
        }
        return R.fail("失败");
    }

    @ApiOperation("新增/修改/删除图片")
    @ApiOperationSupport(order = 4)
    @PostMapping("/saveOrUpdateImg")
    public R<String> saveOrUpdateImg(@RequestBody StoreImgInfoVo storeImgInfoVo) {
        log.info("StoreImgController.saveOrUpdateImg?storeImgInfoVo={}", storeImgInfoVo);
        List<StoreImg> storeImgList = storeImgInfoVo.getStoreImgList();
        if (storeImgInfoVo.getStoreId()==null || storeImgInfoVo.getImgType()==null) {
            return R.fail("失败");
        }
        if(storeImgInfoVo.getStoreImgList().isEmpty()){
            return R.fail("图片列表为空，请重新上传图片");
        }
        Integer imgType = storeImgInfoVo.getImgType();
        Integer storeId = storeImgInfoVo.getStoreId();
        // imgType=38：仅落库 store_img，不走环境相册、门店图片模式、异步取色、头图审核状态等分支
        if (Integer.valueOf(38).equals(imgType)) {
            int deleteCount = storeImgService.saveOrUpdateImg(storeId, imgType);
            log.info("StoreImgController.saveOrUpdateImg imgType=38 store_img only, deleteCount={}", deleteCount);
            for (StoreImg storeImg : storeImgList) {
                if (storeImg != null) {
                    storeImg.setStoreId(storeId);
                    storeImg.setImgType(imgType);
                }
            }
            Integer id = storeImgList.get(0).getId();
            if (storeImgService.saveOrUpdateBatch(storeImgList)) {
                if (id != null) {
                    return R.success("修改成功");
                }
                return R.success("新增成功");
            }
            return R.fail("失败");
        }
        // 图片由前端直连 AI 审核；服务端不再对门店图调用 moderate，避免保存被误拦截（仅与环境相册查询并行占位）
        CompletableFuture<AiContentModerationUtil.AuditResult> auditFuture = CompletableFuture
                .completedFuture(new AiContentModerationUtil.AuditResult(true, null));
        CompletableFuture<List<StoreOfficialAlbum>> albumFuture = (imgType != null && imgType == 4)
                ? CompletableFuture.supplyAsync(() -> storeOfficialAlbumService.lambdaQuery()
                        .eq(StoreOfficialAlbum::getStoreId, storeId)
                        .eq(StoreOfficialAlbum::getAlbumName, "环境")
                        .orderByAsc(StoreOfficialAlbum::getId)
                        .list(), imgAuditExecutor)
                : CompletableFuture.completedFuture(null);
        AiContentModerationUtil.AuditResult auditResult = auditFuture.join();
        if (!auditResult.isPassed()) {
            return R.fail(auditResult.getFailureReason());
        }
//        if (imgType != null && imgType == 4) {
//            List<StoreOfficialAlbum> albumList;
//            try {
//                albumList = albumFuture.get(10, TimeUnit.SECONDS);
//            } catch (Exception e) {
//                log.error("查询环境相册异常", e);
//                return R.fail("查询环境相册失败");
//            }
//            if (albumList == null || albumList.isEmpty()) {
//                return R.fail("没有默认环境相册");
//            }
//            StoreOfficialAlbum album = albumList.get(0);
//            storeImgList.forEach(storeImg -> storeImg.setBusinessId(album.getId()));
//            storeOfficialAlbumService.lambdaUpdate()
//                    .eq(StoreOfficialAlbum::getId, album.getId())
//                    .setSql("img_count = img_count + " + storeImgList.size())
//                    .update();
//        }
        // 此处逻辑修改，前端反馈的是22为头图
        boolean isHeadImage = imgType != null && imgType == 22;
        // 清空storeid,imgType下图片
        int deleteCount = storeImgService.saveOrUpdateImg(storeImgInfoVo.getStoreId(),storeImgInfoVo.getImgType());
        log.info("StoreImgController.updateStoreImgModeInfo?deleteCount={}", deleteCount);
        int result = storeInfoService.updateStoreImgModeInfo(storeImgInfoVo);
        log.info("StoreImgController.updateStoreImgModeInfo?result={}", result);
        
        if(!CollectionUtils.isEmpty(storeImgList)){
            // 判断是否为多图模式
            boolean isMultiMode = imgType != null && imgType.equals(GroupConstant.IMG_TYPE_MULTI_MODE);
            
            // 如果是多图模式，需要找到第一张图片（imgSort最小的）
            StoreImg firstImg = null;
            if (isMultiMode) {
                firstImg = storeImgList.stream()
                        .filter(img -> img != null && img.getImgUrl() != null)
                        .min((img1, img2) -> {
                            Integer sort1 = img1.getImgSort() != null ? img1.getImgSort() : Integer.MAX_VALUE;
                            Integer sort2 = img2.getImgSort() != null ? img2.getImgSort() : Integer.MAX_VALUE;
                            return sort1.compareTo(sort2);
                        })
                        .orElse(null);
            }
            
            // 图片描述按类型固定，只计算一次
            String imgDescription = getImgDescriptionByType(imgType);
            final StoreImg[] needExtractColorImgRef = {null}; // 需要提取颜色的图片（单图模式或多图模式的第一张）
            for (StoreImg storeImg : storeImgList) {
                if (storeImg != null && storeImg.getImgUrl() != null) {
                    if (imgDescription != null) {
                        storeImg.setImgDescription(imgDescription);
                    }
                    
                    // 只有当 is_extract=1 时才标记需要提取颜色
                    Integer isExtract = storeImg.getIsExtract();
                    if (isExtract != null && isExtract == 1) {
                        // 如果是多图模式，只对第一张图片提取颜色
                        if (isMultiMode) {
                            // 判断是否为第一张图片（通过比较imgSort，如果imgSort相同则认为是同一张图片）
                            boolean isFirstImg = firstImg != null && 
                                    firstImg.getImgSort() != null && 
                                    storeImg.getImgSort() != null && 
                                    firstImg.getImgSort().equals(storeImg.getImgSort());
                            
                            if (isFirstImg) {
                                log.info("多图模式，标记第一张图片需要异步提取颜色，imgUrl: {}, imgSort: {}, isExtract: {}", 
                                        storeImg.getImgUrl(), storeImg.getImgSort(), isExtract);
                                needExtractColorImgRef[0] = storeImg;
                            } else {
                                log.info("多图模式，跳过非第一张图片的颜色提取，imgUrl: {}, imgSort: {}", 
                                        storeImg.getImgUrl(), storeImg.getImgSort());
                                // 非第一张图片，保持 is_extract 为 1，但不提取颜色
                            }
                        } else {
                            // 单图模式，标记需要提取颜色
                            log.info("单图模式，标记图片需要异步提取颜色，imgUrl: {}, isExtract: {}", storeImg.getImgUrl(), isExtract);
                            needExtractColorImgRef[0] = storeImg;
                        }
                    }
                }
            }
            Integer id = storeImgList.get(0).getId();
            if (storeImgService.saveOrUpdateBatch(storeImgList)) {
                // 异步提取颜色，不阻塞主流程
                // 保存后，MyBatis-Plus会自动填充ID，需要从保存后的列表中获取
                StoreImg needExtractColorImg = needExtractColorImgRef[0];
                if (needExtractColorImg != null) {
                    // 如果是新增的图片，保存后ID会被自动填充，需要重新查找
                    Integer storeImgId = needExtractColorImg.getId();
                    if (storeImgId == null) {
                        // 新增图片，保存后从列表中查找对应的图片（通过imgUrl匹配）
                        String targetImgUrl = needExtractColorImg.getImgUrl();
                        StoreImg savedImg = storeImgList.stream()
                                .filter(img -> img.getImgUrl() != null && 
                                        img.getImgUrl().equals(targetImgUrl))
                                .findFirst()
                                .orElse(null);
                        if (savedImg != null) {
                            storeImgId = savedImg.getId();
                        }
                    }
                    if (storeImgId != null) {
                        // 调用Service层异步提取颜色方法
                        storeImgService.asyncExtractColorForImg(storeImgId, needExtractColorImg.getImgUrl());
                    }
                }
                
                // 如果是头图，设置审核状态为通过（1），前端已完成门头图识别
                if (isHeadImage) {
                    // 有头图，设置为审核通过状态（1）
                    try {
                        storeInfoService.updateHeadImgStatus(storeImgInfoVo.getStoreId(), 1);
                        log.info("头图保存成功，设置审核状态为通过，storeId={}", storeImgInfoVo.getStoreId());
                    } catch (Exception e) {
                        log.error("更新头图审核状态失败，storeId={}, error={}", 
                                storeImgInfoVo.getStoreId(), e.getMessage(), e);
                    }
                }
                if (null != id) {
                    return R.success("修改成功");
                }
                return R.success("新增成功");
            } else {
                // 图片保存失败，如果是头图，设置审核状态为不通过
                if (isHeadImage) {
                    try {
                        storeInfoService.updateHeadImgStatus(storeImgInfoVo.getStoreId(), 2);
                        log.info("图片保存失败，更新头图审核状态为不通过，storeId={}", storeImgInfoVo.getStoreId());
                    } catch (Exception e) {
                        log.error("更新头图审核状态失败，storeId={}, error={}", 
                                storeImgInfoVo.getStoreId(), e.getMessage(), e);
                    }
                }
            }
        } else {
            // 如果是头图且没有图片，设置审核状态为不通过
            if (isHeadImage) {
                try {
                    storeInfoService.updateHeadImgStatus(storeImgInfoVo.getStoreId(), 2);
                } catch (Exception e) {
                    log.error("更新头图审核状态失败，storeId={}, error={}", 
                            storeImgInfoVo.getStoreId(), e.getMessage(), e);
                }
            }
            return R.success("保存成功");
        }
        return R.fail("失败");
    }


    @ApiOperation(value = "删除图片")
    @ApiOperationSupport(order = 5)
    @PostMapping("/delete")
    public R<String> delete(@RequestBody List<Integer> ids) {
        log.info("StoreImgController.delete?ids={}", ids);
        // 参数校验：ID列表不能为空
        if (ids == null || ids.isEmpty()) {
            log.warn("删除图片失败，ID列表为空");
            return R.fail("删除失败：ID列表不能为空");
        }
        // 过滤掉null值和无效ID
        List<Integer> validIds = ids.stream()
                .filter(id -> id != null && id > 0)
                .collect(Collectors.toList());
        if (validIds.isEmpty()) {
            log.warn("删除图片失败，没有有效的ID");
            return R.fail("删除失败：没有有效的ID");
        }
        if (storeImgService.removeByIds(validIds)) {
            return R.success("删除成功");
        }
        return R.fail("删除失败");
    }

    @ApiOperation("获取轮播图")
    @ApiOperationSupport(order = 6)
    @GetMapping("/getCarouselImage")
    public R<List<StoreImg>> getCarouselImage() {
        return R.data(storeImgService.getCarouselImage());
    }

    @ApiOperation("获取用户打卡广场小人图片")
    @ApiOperationSupport(order = 7)
    @ApiImplicitParams({@ApiImplicitParam(name = "userId", value = "用户id", dataType = "Integer", paramType = "query", required = true)})
    @GetMapping("/getUserClockImg")
    public R<String> getUserClockImg(Integer userId) {
        log.info("StoreImgController.getUserClockImg?userId={}", userId);
        return storeImgService.getUserClockImg(userId);
    }

    @ApiOperation("通过businessId获取图片")
    @ApiOperationSupport(order = 8)
    @ApiImplicitParams({@ApiImplicitParam(name = "storeId", value = "门店id", dataType = "Integer", paramType = "query", required = true),
            @ApiImplicitParam(name = "imgType", value = "图片类型, 0:其他, 1:入口图, 2:相册, 3:菜品, 4:环境, 5:价目表, 6:推荐菜, 7:菜单, 8:用户评论, 9:商家申诉, 10:商家头像, 11:店铺轮播图", dataType = "Integer", paramType = "query", required = true),
            @ApiImplicitParam(name = "businessId", value = "业务ID", dataType = "Integer", paramType = "query", required = true)})
    @GetMapping("/getByBusinessId")
    public R<List<StoreImg>> getByBusinessId(Integer storeId, Integer imgType, Integer businessId) {
        log.info("StoreImgController.getByBusinessId?storeId={}&imgType={}&businessId={}", storeId, imgType, businessId);
        return R.data(storeImgService.getByBusinessId(storeId, imgType, businessId));
    }

    /**
     * 根据图片类型获取图片描述
     *
     * @param imgType 图片类型
     * @return 图片描述
     */
    private String getImgDescriptionByType(Integer imgType) {
        if (imgType == null) {
            return null;
        }
        switch (imgType) {
            case 20:
                return "头图单图模式";
            case 21:
                return "头图多图模式";
            default:
                return null;
        }
    }

    /**
     * 获取封面图片/环境
     *storeId 商家id
     * @param imgType 图片类型
     *                0:其他, 1:入口图, 2:相册, 3:菜品, 4:环境, 5:价目表, 6:推荐菜, 7:菜单, 8:用户评论, 9:商家申诉, 10:商家头像, 11:店铺轮播图，20单图，21多图
     * @return 图片路径
     */
    @ApiOperation("获取封面图片")
    @ApiOperationSupport(order = 8)
    @ApiImplicitParams({@ApiImplicitParam(name = "storeId", value = "门店id", dataType = "Integer", paramType = "query", required = true),
            @ApiImplicitParam(name = "imgType", value = "图片类型, 0:其他, 1:入口图, 2:相册, 3:菜品, 4:环境, 5:价目表, 6:推荐菜, 7:菜单, 8:用户评论, 9:商家申诉, 10:商家头像, 11:店铺轮播图,20单图，21多图", dataType = "Integer", paramType = "query", required = true),
         })
    @GetMapping("/getByCover")
    public R<List<StoreImg>> getByCover(Integer storeId, Integer imgType) {
        log.info("StoreImgController.getByBusinessId?storeId={}&imgType={}", storeId, imgType);
        return R.data(storeImgService.getByCover(storeId, imgType));
    }

}
