package com.cxyxiaomo.epp.shop.controller;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.cxyxiaomo.epp.PageTable.enums.AddType;
import com.cxyxiaomo.epp.PageTable.enums.EditType;
import com.cxyxiaomo.epp.PageTable.enums.FieldType;
import com.cxyxiaomo.epp.PageTable.enums.SearchType;
import com.cxyxiaomo.epp.PageTable.query.PageQuery;
import com.cxyxiaomo.epp.PageTable.utils.FieldBuilder;
import com.cxyxiaomo.epp.PageTable.utils.FieldMapperBuilder;
import com.cxyxiaomo.epp.PageTable.utils.FieldRuleBuilder;
import com.cxyxiaomo.epp.PageTable.utils.FieldRuleListBuilder;
import com.cxyxiaomo.epp.TencentCloud.QCloudCosStsClient;
import com.cxyxiaomo.epp.TencentCloud.TmpCredential;
import com.cxyxiaomo.epp.common.pojo.Good;
import com.cxyxiaomo.epp.common.pojo.GoodCategory;
import com.cxyxiaomo.epp.common.response.Res;
import com.cxyxiaomo.epp.common.vo.GoodCategoryVO;
import com.cxyxiaomo.epp.common.vo.GoodVO;
import com.cxyxiaomo.epp.shop.service.GoodService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/shop/good")
public class GoodController {

    @Resource
    GoodService goodService;

    /**
     * 小程序端商品列表
     *
     * @return
     */
    @GetMapping("/miniprogram/list")
    public Res list(@RequestParam(value = "cateId", required = false) Integer cateId,
                    @RequestParam(value = "searchText", required = false) String searchText) {
        if (cateId != null && cateId <= 0) {
            cateId = null;
        }
        if (searchText != null) {
            searchText = searchText.trim();
            if (searchText.contains("%") || searchText.contains("_")) {
                searchText = searchText
                        .replaceAll("[_%]", "");
            }
            if ("".equals(searchText)) {
                searchText = null;
            }
        }
        List<GoodVO> list = goodService.listOnSale(cateId, searchText);
        return Res.success(list);
    }

    /**
     * 小程序端商品详情
     *
     * @return
     */
    @GetMapping("/miniprogram/detail")
    public Res detail(@RequestParam("id") Long id) {
        GoodVO goodVO = goodService.getById(id);
        return Res.success(goodVO);
    }

    /**
     * 小程序端商品分类列表
     *
     * @return
     */
    @GetMapping("/miniprogram/cateList")
    public Res cateList() {
        List<GoodCategoryVO> list = goodService.cateListVO();
        return Res.success(list);
    }


    /**
     * 获取商品列表
     *
     * @return
     */
    @GetMapping("/manage/getGoodList")
    @ResponseBody
    public Res getGoodList(PageQuery pageQuery, GoodVO goodVO) {
        // 查询分页数据
        PageHelper.startPage(pageQuery.getPageIndex(), pageQuery.getPageSize());
        List<Good> goodList = goodService.getGoodList(goodVO);
        PageInfo<Good> goodPageInfo = new PageInfo<>(goodList);
        List<Good> list = goodPageInfo.getList();
        List<GoodVO> voList = GoodVO.convertFrom(list);

        // 分类列表
        List<GoodCategory> cateList = goodService.getCateList();
        String cateListForMock = JSONArray.from(cateList.stream()
                .map(i -> i.getId().toString()).collect(Collectors.toList())).toString();

        // id列 字段名（区分大小写；以VO中的变量名为准）
        // 新增、修改弹窗时，使用该列作为主键列进行操作
        String idFieldName = "id";

        // 当前管理页面
        String pageName = "商品管理";

        // 指定前端表格显示列
        JSONArray columns = FieldBuilder.create()
                .add("picUrl", "picUrl", "商品图片", "https://cdn-we-retail.ym.tencent.com/tsr/goods/muy-3a.png?imageMogr2/thumbnail/320x320/quality/70/strip/format/jpg",
                        FieldType.IMAGE, SearchType.CAN_NOT_SEARCH, AddType.IMAGE, EditType.IMAGE,
                        FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
                        "商品图片", FieldBuilder.EDIT_PLACEHOLDER_SAME_AS_ADD_PLACEHOLDER,
                        FieldRuleListBuilder.create(),
                        null // "IMG 120x120,随机图片"
                )
                .add("goodsName", "goodsName", "商品名称", "",
                        FieldType.TEXT, SearchType.INPUT, AddType.INPUT, EditType.INPUT,
                        FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
                        "商品名称", FieldBuilder.EDIT_PLACEHOLDER_SAME_AS_ADD_PLACEHOLDER,
                        FieldRuleListBuilder.create()
                                .add(FieldRuleBuilder.create("商品名称").required())
                                .add(FieldRuleBuilder.create("商品名称").minMax(6, 20)),
                        "DPD @cword(6, 20)"
                )
                .add("categoryId", "categoryName", "所属分类", "",
                        FieldType.TEXT, SearchType.SELECT, AddType.SELECT, EditType.SELECT,
                        "商品分类",
                        "商品分类", FieldBuilder.EDIT_PLACEHOLDER_SAME_AS_ADD_PLACEHOLDER,
                        FieldRuleListBuilder.create()
                                .add(FieldRuleBuilder.create("商品分类").required()),
                        "DPD @pick(" + cateListForMock + ")"
                )
                .add("brand", "brand", "商品品牌", "",
                        FieldType.TEXT, SearchType.INPUT, AddType.INPUT, EditType.INPUT,
                        FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
                        "商品品牌", FieldBuilder.EDIT_PLACEHOLDER_SAME_AS_ADD_PLACEHOLDER,
                        FieldRuleListBuilder.create()
                                .add(FieldRuleBuilder.create("商品品牌").required())
                                .add(FieldRuleBuilder.create("商品品牌").minMax(6, 20)),
                        "DPD @cword(6, 15)"
                )
                .add("brief", "brief", "商品简介", "暂无简介",
                        FieldType.HIDDEN, SearchType.INPUT, AddType.INPUT, EditType.INPUT,
                        FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
                        "商品简介", FieldBuilder.EDIT_PLACEHOLDER_SAME_AS_ADD_PLACEHOLDER,
                        FieldRuleListBuilder.create()
                                .add(FieldRuleBuilder.create("商品简介").required())
                                .add(FieldRuleBuilder.create("商品简介").minMax(6, 30)),
                        "DPD @cword(15, 30)"
                )
                .add("isOnSale", "isOnSaleDisplay", "状态", true,
                        FieldType.TEXT, SearchType.SELECT, AddType.SELECT, EditType.SELECT,
                        FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
                        "状态", FieldBuilder.EDIT_PLACEHOLDER_SAME_AS_ADD_PLACEHOLDER,
                        FieldRuleListBuilder.create()
                                .add(FieldRuleBuilder.create("状态").required()),
                        "DPD @pick(['true', 'false'])"
                )
                .add("sortOrder", "sortOrder", "排序", "",
                        FieldType.TEXT, SearchType.INPUT, AddType.INPUT, EditType.INPUT,
                        FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
                        "排序", FieldBuilder.EDIT_PLACEHOLDER_SAME_AS_ADD_PLACEHOLDER,
                        FieldRuleListBuilder.create(),
                        "DTD /^\\d+?$/"
                )
                .add("unit", "unit", "商品单位", "个",
                        FieldType.TEXT, SearchType.CAN_NOT_SEARCH, AddType.INPUT, EditType.INPUT,
                        FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
                        "商品单位", FieldBuilder.EDIT_PLACEHOLDER_SAME_AS_ADD_PLACEHOLDER,
                        FieldRuleListBuilder.create()
                                .add(FieldRuleBuilder.create("商品单位").required()),
                        "DPD @cword(1, 2)"
                )
                .add("counterPrice", "counterPrice", "专柜价格", "",
                        FieldType.TEXT, SearchType.INPUT, AddType.INPUT_NUMBER, EditType.INPUT_NUMBER,
                        "专柜价/原价/划线价",
                        "专柜价格 / 原价 / 划线价", FieldBuilder.EDIT_PLACEHOLDER_SAME_AS_ADD_PLACEHOLDER,
                        FieldRuleListBuilder.create()
                                .add(FieldRuleBuilder.create("专柜价格").required())
                        // .add(FieldRuleBuilder.create("专柜价格").regexp("^(\\d+(\\.\\d{1,2})?)$"))
                        ,
                        "DTD /^[1-9]\\d{0,4}(\\.?\\d{1,2})?$/"
                )
                .add("retailPrice", "retailPrice", "零售价格", "",
                        FieldType.TEXT, SearchType.INPUT, AddType.INPUT_NUMBER, EditType.INPUT_NUMBER,
                        "零售价/售价/未划线价",
                        "零售价 / 售价 / 未划线价", FieldBuilder.EDIT_PLACEHOLDER_SAME_AS_ADD_PLACEHOLDER,
                        FieldRuleListBuilder.create()
                                .add(FieldRuleBuilder.create("零售价格").required())
                        // .add(FieldRuleBuilder.create("零售价格").regexp("^(\\d+(\\.\\d{1,2})?)$"))
                        ,
                        "DTD /^[1-9]\\d{0,2}(\\.?\\d{1,2})?$/"
                )
                .add("detail", "detail", "商品详细介绍", "暂无商品详细介绍",
                        FieldType.LONG_TEXT, SearchType.INPUT, AddType.TEXTAREA, EditType.TEXTAREA,
                        "详细介绍",
                        "商品详细介绍", FieldBuilder.EDIT_PLACEHOLDER_SAME_AS_ADD_PLACEHOLDER,
                        FieldRuleListBuilder.create(),
                        "DPD @csentence(20, 200)"
                )
                .build();

        // 指定需要翻译的字段
        HashMap cateMap = new HashMap(cateList.size());
        for (GoodCategory category : cateList) {
            cateMap.put(category.getId(), category.getCategoryName());
        }
        HashMap<Object, Object> stateMap = new HashMap<>(2);
        stateMap.put(true, "上架");
        stateMap.put(false, "下架");
        // build
        JSONArray fieldMapper = FieldMapperBuilder.create()
                .add("categoryId", "categoryName", cateMap)
                .add("isOnSale", "isOnSaleDisplay", stateMap)
                .build();

        // 拼装返回结果
        JSONObject map = new JSONObject(6);
        map.put("total", goodPageInfo.getTotal());
        map.put("list", voList);
        map.put("columns", columns);
        map.put("fieldMapper", fieldMapper);
        map.put("idFieldName", idFieldName);
        map.put("pageName", pageName);

        // 返回结果
        return Res.success(map);
    }

    /**
     * 新增 / 编辑商品
     *
     * @return
     */
    @PostMapping("/manage/editGood")
    @ResponseBody
    public Res editGood(@ModelAttribute GoodVO goodVO) {
        Good good = GoodVO.convertTo(goodVO);
        Double retailPrice = good.getRetailPrice();
        if (Objects.nonNull(retailPrice)) {
            if (retailPrice < 0 || retailPrice > 99999999.99) {
                return Res.error("零售价格输入不符，须在 0 - 99999999.99 之间");
            }
        }
        Double counterPrice = good.getCounterPrice();
        if (Objects.nonNull(counterPrice)) {
            if (counterPrice < 0 || counterPrice > 99999999.99) {
                return Res.error("专柜价格输入不符，须在 0 - 99999999.99 之间");
            }
        }

        // 先查询商品是否存在
        Good existGood = goodService.getGoodById(good.getId());

        if (good.getId() == null || good.getId() < 1) {
            // 新增商品
            if (existGood != null) {
                return Res.error("商品已存在，操作失败");
            }

            if (good.getGoodsName() == null || "".equals(good.getGoodsName())) {
                return Res.error("商品名称不能为空");
            }
            good.setId(null);
            goodService.addGood(good);
        } else {
            // 修改商品
            if (existGood == null) {
                return Res.error("商品不存在，操作失败");
            }

            goodService.updateGood(good);
        }
        return Res.success(true);
    }

    /**
     * 删除商品
     *
     * @param id
     * @return
     */
    @PostMapping("/manage/deleteGood")
    @ResponseBody
    public Res deleteGood(Long id) {
        if (id == null || id <= 0) {
            return Res.error("商品不存在，删除失败");
        }
        // 先查询商品是否存在
        Good existGood = goodService.getGoodById(id);
        if (existGood == null) {
            return Res.error("商品不存在，删除失败");
        }
        boolean b = goodService.deleteGood(existGood.getId());
        return Res.success(b);
    }

    /**
     * 导出商品列表
     *
     * @return
     */
    @GetMapping("/manage/exportGoodList")
    @ResponseBody
    public Res exportGoodList(GoodVO goodVO) {
        List<Good> goodList = goodService.getGoodList(goodVO);
        List<GoodVO> goodVOList = GoodVO.convertFrom(goodList);

        // 当前时间
        Date now = Calendar.getInstance().getTime();
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd_HHmmss");
        String dateTime = format.format(now);

        HashMap<String, Object> map = new HashMap<>();
        map.put("list", goodVOList);
        map.put("sheetName", "商品表-" + System.currentTimeMillis());
        map.put("fileName", "商品表_导出时间_" + dateTime);

        return Res.success(map);
    }

    /**
     * 上传商品图片到腾讯云COS桶
     * —— 获取上传临时密钥及生成文件名
     *
     * @param ext
     * @return
     */
    @GetMapping("/manage/imageUpload/getTmpCosCredential")
    @ResponseBody
    public Res getTmpCosCredential(@RequestParam(required = true) String ext) {
        // 生成一个随机文件名
        UUID uuid = UUID.randomUUID();
        String objectKey = "good/" + uuid + "." + ext;
        // 创建一个临时密钥
        TmpCredential credential = QCloudCosStsClient.getCredential(objectKey);
        // 返回结果
        return Res.success(credential);
    }


    /**
     * 获取商品分类
     *
     * @return
     */
    @GetMapping("/manage/getCategoryList")
    @ResponseBody
    public Res getCategoryList(PageQuery pageQuery, GoodCategoryVO goodCategoryVO) {
        // 查询分页数据
        PageHelper.startPage(pageQuery.getPageIndex(), pageQuery.getPageSize());
        List<GoodCategory> goodCategoryList = goodService.getCateListWithQuery(goodCategoryVO);
        PageInfo<GoodCategory> goodCategoryPageInfo = new PageInfo<>(goodCategoryList);
        List<GoodCategory> list = goodCategoryPageInfo.getList();
        List<GoodCategoryVO> voList = GoodCategoryVO.convertFrom(list);

        // id列 字段名（区分大小写；以VO中的变量名为准）
        // 新增、修改弹窗时，使用该列作为主键列进行操作
        String idFieldName = "id";

        // 当前管理页面
        String pageName = "分类管理";

        // 指定前端表格显示列
        JSONArray columns = FieldBuilder.create()
                .add("categoryName", "categoryName", "商品分类", "",
                        FieldType.TEXT, SearchType.INPUT, AddType.INPUT, EditType.INPUT,
                        FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
                        "商品分类", FieldBuilder.EDIT_PLACEHOLDER_SAME_AS_ADD_PLACEHOLDER,
                        FieldRuleListBuilder.create()
                                .add(FieldRuleBuilder.create("商品分类").required())
                                .add(FieldRuleBuilder.create("商品分类").minMax(2, 4)),
                        "DPD @cword(2, 4)"
                )
                .add("order", "order", "排序", "",
                        FieldType.TEXT, SearchType.CAN_NOT_SEARCH, AddType.INPUT, EditType.INPUT,
                        FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
                        "排序", FieldBuilder.EDIT_PLACEHOLDER_SAME_AS_ADD_PLACEHOLDER,
                        FieldRuleListBuilder.create(),
                        "DTD /^\\d+?$/"
                )
                .build();

        // 指定需要翻译的字段
        JSONArray fieldMapper = FieldMapperBuilder.create()
                .build();

        // 拼装返回结果
        JSONObject map = new JSONObject(6);
        map.put("total", goodCategoryPageInfo.getTotal());
        map.put("list", voList);
        map.put("columns", columns);
        map.put("fieldMapper", fieldMapper);
        map.put("idFieldName", idFieldName);
        map.put("pageName", pageName);

        // 返回结果
        return Res.success(map);
    }

    /**
     * 新增 / 编辑分类
     *
     * @return
     */
    @PostMapping("/manage/editCategory")
    @ResponseBody
    public Res editCategory(@ModelAttribute GoodCategoryVO goodCategoryVO) {
        GoodCategory goodCategory = GoodCategoryVO.convertTo(goodCategoryVO);

        // 先查询分类是否存在
        GoodCategory existGoodCategory = goodService.getGoodCategoryById(goodCategory.getId());

        if (goodCategory.getId() == null || goodCategory.getId() < 1) {
            // 新增分类
            if (existGoodCategory != null) {
                return Res.error("分类已存在，操作失败");
            }

            if (goodCategory.getCategoryName() == null || "".equals(goodCategory.getCategoryName())) {
                return Res.error("分类名称不能为空");
            }
            goodCategory.setId(null);
            goodService.addGoodCategory(goodCategory);
        } else {
            // 修改分类
            if (existGoodCategory == null) {
                return Res.error("分类不存在，操作失败");
            }

            goodService.updateGoodCategory(goodCategory);
        }
        return Res.success(true);
    }

    /**
     * 删除分类
     *
     * @param id
     * @return
     */
    @PostMapping("/manage/deleteCategory")
    @ResponseBody
    public Res deleteCategory(Long id) {
        if (id == null || id <= 0) {
            return Res.error("分类不存在，删除失败");
        }
        // 先查询分类是否存在
        GoodCategory existGoodCategory = goodService.getGoodCategoryById(id);
        if (existGoodCategory == null) {
            return Res.error("分类不存在，删除失败");
        }
        boolean b = goodService.deleteGoodCategory(existGoodCategory.getId());
        return Res.success(b);
    }

    /**
     * 导出分类列表
     *
     * @return
     */
    @GetMapping("/manage/exportCategoryList")
    @ResponseBody
    public Res exportCategoryList(GoodCategoryVO goodCategoryVO) {
        List<GoodCategory> categoryList = goodService.getCateListWithQuery(goodCategoryVO);
        List<GoodCategoryVO> goodCategoryVOList = GoodCategoryVO.convertFrom(categoryList);

        // 当前时间
        Date now = Calendar.getInstance().getTime();
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd_HHmmss");
        String dateTime = format.format(now);

        HashMap<String, Object> map = new HashMap<>();
        map.put("list", goodCategoryVOList);
        map.put("sheetName", "商品分类表-" + System.currentTimeMillis());
        map.put("fileName", "商品分类表_导出时间_" + dateTime);

        return Res.success(map);
    }
}
