package com.ruoyi.demo.controller;

import cn.dev33.satoken.stp.StpUtil;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.demo.constant.RedisContant;
import com.ruoyi.demo.entity.bo.BrandGeoLabelBo;
import com.ruoyi.demo.entity.vo.BrandEvolveVo;
import com.ruoyi.demo.entity.vo.ListQueryBody;
import com.ruoyi.demo.entity.vo.OpcloseTimeVo;
import com.ruoyi.demo.service.BrandService;
import com.ruoyi.demo.utils.HashUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/brand")
public class BrandController extends BaseController {
    @Autowired
    private BrandService brandService;
    @Autowired
    RedisTemplate redisTemplate;

    /**
     * 获取品牌搜索推荐
     *
     * @param text 搜索关键字
     * @return
     */
    @GetMapping("/search")
    public R search(String text) {
        return R.ok(brandService.searchByLikeName(text));
    }

    /**
     * 获取品牌信息列表
     *
     * @param body 关键字、网点数量、覆盖城市数和地区码查询请求体
     * @return
     */
    @PostMapping("/list")
    public R list(ListQueryBody body) {
        String loginId = String.valueOf(StpUtil.getLoginId());
        Long userid = Long.valueOf(loginId.split(":")[1]);
        String userId = userid.toString();
        return R.ok(brandService.searchListByMulti(body, userId));
    }

    /**
     * 获取品牌详细信息
     *
     * @param brandId 品牌id
     * @return
     */
    @GetMapping("/info")
    public R info(String brandId) {
        String loginId = String.valueOf(StpUtil.getLoginId());
        Long userid = Long.valueOf(loginId.split(":")[1]);
        String userId = userid.toString();
        return R.ok(brandService.searchByBrandId(brandId, userId));
    }

    /**
     * 获取品牌物业信息
     *
     * @param brandId 品牌id
     * @return
     */
    @GetMapping("/property")
    public R property(String brandId) {
        return R.ok(brandService.searchPropertyByBrandId(brandId));
    }

    /**
     * 获取品牌地区分布词云
     *
     * @param brandId 品牌id
     * @return
     */
    @GetMapping("/distribution")
    public R distribution(String brandId) {
        return R.ok(brandService.searchDisCloudByBrandId(brandId));
    }

    /**
     * 获取相似品牌
     *
     * @param brandId 品牌id
     * @return
     */
    @GetMapping("/similar")
    public R similar(String brandId) {
        return R.ok(brandService.searchSimilarByBrandId(brandId));
    }

    /**
     * 获取品牌网点营业状态分布
     *
     * @param brandId 品牌id
     * @return
     */
    @GetMapping("/status")
    public R statusDistribution(String brandId) {
        return R.ok(brandService.searchStatusByBrandId(brandId));
    }

    /**
     * 获取品牌网点地图信息
     *
     * @param brandId 品牌id
     * @return
     */
    @GetMapping("/area")
    public R area(String brandId) {
        return R.ok(brandService.searchProvinceByBrandId(brandId));
    }

    /**
     * 获取品牌网点数量及其城市数量分布
     *
     * @param brandId 品牌id
     * @return
     */
    @GetMapping("/shopCount")
    public R shopCount(String brandId) {
        return R.ok(brandService.searchDistributionByBrandId(brandId));
    }

    /**
     * 品牌网点数量对比
     *
     * @param pageSize 返回数据大小
     * @return
     */
    @GetMapping("/total")
    public R total(Integer pageSize) {
        return R.ok(brandService.searchTotal(pageSize));
    }

    /**
     * 获取品牌地理位置标签分布
     *
     * @param brandId 品牌id
     * @return
     */
    @GetMapping("/geolabel")
    public R geolabel(String brandId) {
        // 获取redis缓存
        String md5 = HashUtil.hash(brandId, "MD5");
        List<BrandGeoLabelBo> bos = (List<BrandGeoLabelBo>) redisTemplate.boundHashOps(RedisContant.BRAND_GEOLABEL).get(md5);
        if (bos != null) return R.ok(bos);

        // 缓存中没有则计算一次
        List<BrandGeoLabelBo> brandGeoLabelBos = brandService.searchGeoLabel(brandId);
        // 放入redis中
        redisTemplate.boundHashOps(RedisContant.BRAND_GEOLABEL).put(md5, brandGeoLabelBos);
        redisTemplate.expire(RedisContant.BRAND_GEOLABEL, RedisContant.BRAND_GEOLABEL_TIME, TimeUnit.MINUTES);

        return R.ok(brandGeoLabelBos);
    }

    /**
     * 行业连锁品牌发展情况
     *
     * @param body 地址码、分类码和品牌ids查询请求体
     * @return
     */
    @PostMapping("/evolve")
    public R develop(@RequestBody ListQueryBody body) {
        List<String> addrCode = body.getAddrCode();
        List<String> brandId = body.getBrandId();
        if (brandId == null || brandId.size() == 0) return R.fail("brandId不允许为空");

        // 获取redis缓存
        String md5 = HashUtil.hash(addrCode.toString() + brandId.toString(), "MD5");
        Map<String, List<BrandEvolveVo>> map = (Map<String, List<BrandEvolveVo>>) redisTemplate.boundHashOps(RedisContant.BRAND_EVOLVE).get(md5);
        if (map != null) return R.ok(map);

        // Map<String, List<BrandEvolveVo>> stringListMap = brandService.searchEvolveByMulti(addrCode, typeCode, brandId);
        Map<String, List<BrandEvolveVo>> listMap = brandService.searchEvolveByMulti2Map(addrCode, null, brandId);

        redisTemplate.boundHashOps(RedisContant.BRAND_EVOLVE).put(md5, listMap);
        redisTemplate.expire(RedisContant.BRAND_EVOLVE, RedisContant.BRAND_EVOLVE_TIME, TimeUnit.MINUTES);

        return R.ok(listMap);

    }

    /**
     * 品牌各地区网点开店时间分布情况
     *
     * @param body 地址码、分类码和品牌ids查询请求体
     * @return
     */
    @PostMapping("/opentime")
    public R openTime(@RequestBody ListQueryBody body) {
        List<String> brandIds = body.getBrandId();
        List<String> addrCodes = body.getAddrCode();
        List<String> typeCodeBys = body.getTypeCodeBy();
        List<OpcloseTimeVo> vos = brandService.searchOpenTims(brandIds, addrCodes, typeCodeBys);
        return R.ok(vos);
    }

    /**
     * 品牌各地区网点关店时间分布情况
     *
     * @param body 地址码、分类码和品牌ids查询请求体
     * @return
     */
    @PostMapping("/closetime")
    public R closeTime(@RequestBody ListQueryBody body) {
        List<String> brandIds = body.getBrandId();
        List<String> addrCodes = body.getAddrCode();
        List<String> typeCodeBys = body.getTypeCodeBy();
        List<OpcloseTimeVo> vos = brandService.searchCloseTims(brandIds, addrCodes, typeCodeBys);
        return R.ok(vos);
    }

    /**
     * 城市等级分布
     *
     * @param brandId 品牌id
     * @return
     */
    @GetMapping("/level")
    public R level(@NotBlank(message = "品牌id不能为空") String brandId) {
        return R.ok(brandService.getCityTier(brandId));
    }

    /**
     * 行业新品牌
     *
     * @param bo 地址码和网点类型（犇云）查询体
     * @return
     */
    @GetMapping("/new")
    public R newBrand(ListQueryBody bo) {
        List<String> industryCodes = bo.getIndustryCode();
        return R.ok(brandService.searchNew(industryCodes));
    }
}
