
package com.tmerclub.cloud.user.controller.multishop;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.tmerclub.cloud.common.database.dto.PageDTO;
import com.tmerclub.cloud.common.database.vo.PageVO;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.common.security.AuthUserContext;
import com.tmerclub.cloud.common.util.BeanUtil;
import com.tmerclub.cloud.user.constant.PopupPageTypeEnum;
import com.tmerclub.cloud.user.constant.PopupStatusEnum;
import com.tmerclub.cloud.user.constant.PopupUserTypeEnum;
import com.tmerclub.cloud.user.constant.PushFrequencyEnum;
import com.tmerclub.cloud.user.dto.CostPerPopupDTO;
import com.tmerclub.cloud.user.model.CostPerPopup;
import com.tmerclub.cloud.user.service.CostPerPopupService;
import com.tmerclub.cloud.user.vo.CostPerPopupVO;
import com.tmerclub.cloud.user.vo.PopupRelateVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;

/**
 * 弹窗广告
 * @author TRACK
 */
@RestController("multishopCostPerPopupController")
@RequestMapping("/m/costPerPopup")
@Tag(name = "multishop-弹窗广告")
public class CostPerPopupController {

    @Autowired
    private CostPerPopupService costPerPopupService;

    @GetMapping("/page")
    @Operation(summary = "获取弹窗广告列表", description = "分页获取弹窗广告列表")
    public ServerResponseEntity<PageVO<CostPerPopupVO>> page(PageDTO pageDTO, CostPerPopupDTO costPerPopupDTO) {
        costPerPopupDTO.setShopId(AuthUserContext.get().getTenantId());
        PageVO<CostPerPopupVO> costPerPopupPage = costPerPopupService.page(pageDTO, costPerPopupDTO);
        return ServerResponseEntity.success(costPerPopupPage);
    }

    @GetMapping
    @Operation(summary = "获取弹窗广告", description = "根据popupId获取弹窗广告")
    public ServerResponseEntity<CostPerPopupVO> getByPopupId(@RequestParam Long popupId) {
        CostPerPopupVO popup = costPerPopupService.getByPopupId(popupId);
        costPerPopupService.handleInfo(popup);
        return ServerResponseEntity.success(popup);
    }

    @PostMapping
    @Operation(summary = "保存弹窗广告", description = "保存弹窗广告")
    public ServerResponseEntity<Void> save(@Valid @RequestBody CostPerPopupDTO costPerPopupDTO) {
        CostPerPopup costPerPopup = BeanUtil.map(costPerPopupDTO, CostPerPopup.class);
        costPerPopup.setPopupId(null);
        costPerPopup.setShopId(AuthUserContext.get().getTenantId());
        costPerPopup.setStatus(PopupStatusEnum.NOT_START.value());
        checkInfo(costPerPopup);
        costPerPopupService.save(costPerPopup);
        return ServerResponseEntity.success();
    }

    @PutMapping
    @Operation(summary = "更新弹窗广告", description = "更新弹窗广告")
    public ServerResponseEntity<Void> update(@Valid @RequestBody CostPerPopupDTO costPerPopupDTO) {
        CostPerPopup costPerPopup = BeanUtil.map(costPerPopupDTO, CostPerPopup.class);
        checkInfo(costPerPopup);
        costPerPopupService.update(costPerPopup);
        return ServerResponseEntity.success();
    }

    @DeleteMapping
    @Operation(summary = "删除弹窗广告", description = "根据弹窗广告id删除弹窗广告")
    public ServerResponseEntity<Void> delete(@RequestParam Long popupId) {
        costPerPopupService.deleteById(popupId);
        return ServerResponseEntity.success();
    }

    @PutMapping("/invalid")
    @Operation(summary = "失效弹窗广告", description = "根据弹窗广告id失效弹窗广告")
    public ServerResponseEntity<Void> invalid(@RequestParam Long popupId) {
        costPerPopupService.invalid(popupId);
        return ServerResponseEntity.success();
    }

    private void checkInfo(CostPerPopup costPerPopup) {
        costPerPopup.setUserLevelIds(null);
        if (!PopupPageTypeEnum.isShop(costPerPopup.getPageType())) {
            throw new LuckException("触发页面类型错误");
        }
        if (!PopupUserTypeEnum.isShop(costPerPopup.getUserType())) {
            throw new LuckException("推送用户类型错误");
        }
        if (Objects.equals(costPerPopup.getPageType(), PopupPageTypeEnum.SPU_DETAIL.value()) && CollUtil.isEmpty(costPerPopup.getSpuIds())) {
            throw new LuckException("关联商品不能为空");
        }
        if (Objects.equals(costPerPopup.getPushFrequency(), PushFrequencyEnum.CUSTOM.value())) {
            if (Objects.nonNull(costPerPopup.getDayFrequency()) && StrUtil.isNotBlank(costPerPopup.getWeekFrequency())) {
                throw new LuckException("推送天数/周不能同时存在");
            }
            if (Objects.isNull(costPerPopup.getDayFrequency()) && StrUtil.isBlank(costPerPopup.getWeekFrequency())) {
                throw new LuckException("推送天数/周不能为空");
            }
        }
        // 校验重复
        List<CostPerPopupVO> dbList = costPerPopupService.listByParam(costPerPopup);
        if (CollUtil.isEmpty(dbList)) {
            return;
        }
        boolean checkFrequency = Objects.equals(costPerPopup.getPushFrequency(), PushFrequencyEnum.CUSTOM.value()) && StrUtil.isNotBlank(costPerPopup.getWeekFrequency());
        if (checkFrequency) {
            // 只有按周推送需要再校验一下周数重复
            for (CostPerPopupVO costPerPopupVO : dbList) {
                if (!Objects.equals(costPerPopupVO.getPushFrequency(), PushFrequencyEnum.CUSTOM.value()) || StrUtil.isBlank(costPerPopupVO.getWeekFrequency())) {
                    checkSingle(costPerPopup, costPerPopupVO);
                } else {
                    // 按周推送的检查是否有重复周
                    List<String> duplicateList = costPerPopupService.getDuplicateList(costPerPopup, costPerPopupVO);
                    if (CollUtil.isNotEmpty(duplicateList)) {
                        checkSingle(costPerPopup, costPerPopupVO);
                    }
                }
            }
            return;
        }
        if (Objects.equals(costPerPopup.getPageType(), PopupPageTypeEnum.SHOP_HOME.value())) {
            throw new LuckException("已有重复弹窗广告");
        }
        for (CostPerPopupVO costPerPopupVO : dbList) {
            checkSpu(costPerPopup, costPerPopupVO);
        }
    }

    private static void checkSingle(CostPerPopup costPerPopup, CostPerPopupVO costPerPopupVO) {
        if (Objects.equals(costPerPopup.getPageType(), PopupPageTypeEnum.SHOP_HOME.value())) {
            throw new LuckException("已有重复弹窗广告");
        }
        checkSpu(costPerPopup, costPerPopupVO);
    }

    private static void checkSpu(CostPerPopup costPerPopup, CostPerPopupVO costPerPopupVO) {
        List<Long> dbSpuIds = costPerPopupVO.getPopupRelateList().stream().map(PopupRelateVO::getSpuId).toList();
        List<Long> duplicateList = dbSpuIds.stream().filter(costPerPopup.getSpuIds()::contains).toList();
        if (CollUtil.isNotEmpty(duplicateList)) {
            throw new LuckException("关联商品中已有弹窗广告");
        }
    }
}
