package com.slodon.b2b2c.controller.seller.front;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.slodon.b2b2c.aop.OperationLogger;
import com.slodon.b2b2c.core.config.DomainUrlUtil;
import com.slodon.b2b2c.core.constant.ResponseConst;
import com.slodon.b2b2c.core.constant.StoreCateConst;
import com.slodon.b2b2c.core.constant.StoreConst;
import com.slodon.b2b2c.core.constant.VendorConst;
import com.slodon.b2b2c.core.exception.MallException;
import com.slodon.b2b2c.core.response.JsonResult;
import com.slodon.b2b2c.core.response.PageVO;
import com.slodon.b2b2c.core.response.PagerInfo;
import com.slodon.b2b2c.core.response.SldResponse;
import com.slodon.b2b2c.core.util.StringUtil;
import com.slodon.b2b2c.core.util.TimeUtil;
import com.slodon.b2b2c.core.util.UserUtil;
import com.slodon.b2b2c.core.util.WebUtil;
import com.slodon.b2b2c.enums.SeoTypeConstant;
import com.slodon.b2b2c.enums.WebSiteConstant;
import com.slodon.b2b2c.goods.dto.SearchProductDTO;
import com.slodon.b2b2c.member.example.MemberFollowStoreExample;
import com.slodon.b2b2c.member.pojo.Member;
import com.slodon.b2b2c.member.pojo.MemberFollowStore;
import com.slodon.b2b2c.model.goods.ESGoodsModel;
import com.slodon.b2b2c.model.goods.GoodsModel;
import com.slodon.b2b2c.model.goods.StoreCertificateNewListModel;
import com.slodon.b2b2c.model.member.MemberFollowStoreModel;
import com.slodon.b2b2c.model.seller.*;
import com.slodon.b2b2c.seller.example.*;
import com.slodon.b2b2c.seller.pojo.*;
import com.slodon.b2b2c.vo.goods.SysSeoVO;
import com.slodon.b2b2c.vo.seller.FrontStoreListVO;
import com.slodon.b2b2c.vo.seller.FrontStoreVO;
import com.slodon.b2b2c.vo.seller.StoreCategoryTreeVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;

/**
 * @author slodon
 */
@Api(tags = "front-店铺接口")
@RestController
@Slf4j
@RequestMapping("v3/seller/front/store")
public class FrontStoreController {

    @Resource
    private StoreModel storeModel;
    @Resource
    private StoreNameModel storeNameModel;
    @Resource
    private StoreSiteInfoModel storeSiteInfoModel;
    @Resource
    private VendorModel vendorModel;
    @Resource
    private StoreCertificateModel storeCertificateModel;
    @Resource
    private StoreInnerLabelModel storeInnerLabelModel;
    @Resource
    private MemberFollowStoreModel memberFollowStoreModel;
    @Resource
    private GoodsModel goodsModel;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private ESGoodsModel esGoodsModel;
    @Resource
    private StoreCertificateNewListModel storeCertificateNewListModel;

    @Resource
    private StoreProfileModel storeProfileModel;
    @Resource
    private StoreProfileTextListModel storeProfileTextListModel;
    @Resource
    private SellerStoreCompanyShowModel sellerStoreCompanyShowModel;


    @ApiOperation("获取店铺列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "categoryId", value = "三级分类id", paramType = "query"),
            @ApiImplicitParam(name = "keyword", value = "关键词", paramType = "query"),
            @ApiImplicitParam(name = "sort", value = "排序条件：1-销量排序，2-人气排序，默认1", defaultValue = "1", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "分页大小", defaultValue = "20", paramType = "query"),
            @ApiImplicitParam(name = "current", value = "当前页面位置", defaultValue = "1", paramType = "query")
    })
    @GetMapping("list")
    public JsonResult<PageVO<FrontStoreListVO>> getList(HttpServletRequest request, Integer categoryId,
                                                        @RequestParam(value = "keyword", required = false) String keyword,
                                                        @RequestParam(value = "sort", required = false, defaultValue = "2") Integer sort) {
        String webSite = WebUtil.getWebSite(request);
        Member member = UserUtil.getUser(request, Member.class);
        List<Store> storeList = new ArrayList<>();
        PagerInfo pager = WebUtil.handlerPagerInfo(request);
        List<FrontStoreListVO> vos = new ArrayList<>();
        StoreExample storeExample = new StoreExample();
        storeExample.setState(StoreConst.STORE_STATE_OPEN);

        storeExample.setStoreNameLike(keyword);
        storeExample.setBusinessState(StoreConst.STORE_BUSINESS_STATE_OPEN);

        if (sort == 2) {
            storeExample.setOrderBy("store_look_volume DESC");
        } else {
            storeExample.setOrderBy("store_sales_volume DESC");
        }
        if (WebSiteConstant.MEMBER_OVERSEA.equals(webSite)) {
            storeList = storeModel.getStoreList(storeExample, pager);
        } else {
            if (pager != null) {
                storeList = storeModel.getStoreCnList(storeExample, pager);
            }
        }
        if (CollectionUtils.isEmpty(storeList)) {
            //没有满足条件的店铺
            return SldResponse.success(new PageVO<>(vos, pager));
        }

        for (Store store : storeList) {
            //默认店铺logo
            if (StringUtils.isEmpty(store.getStoreLogo())) {
                store.setStoreLogo(stringRedisTemplate.opsForValue().get("default_image_store_logo"));
            }
            //默认店铺背景图片(取移动端横幅)
            if (StringUtils.isEmpty(store.getStoreBannerMobile())) {
                store.setStoreBannerMobile(stringRedisTemplate.opsForValue().get("default_image_store_backdrop"));
            }
            FrontStoreListVO vo = new FrontStoreListVO(store);
            vos.add(vo);
        }

        return SldResponse.success(new PageVO<>(vos, pager));
    }

    @ApiOperation("获取店铺详情接口")
    @OperationLogger(option = "获取店铺详情接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "storeId", value = "店铺id", required = true)
    })
    @GetMapping("detail")
    public JsonResult<FrontStoreVO> detail(HttpServletRequest request, @RequestParam("storeId") Long storeId) throws IOException, WriterException {
        Member member = UserUtil.getUser(request, Member.class);
        String webSite = WebUtil.getWebSite(request);
        Store store = storeModel.getStoreByStoreId(storeId);
        Integer state = store.getState();
        String serviceScore = store.getServiceScore();
        String deliverScore = store.getDeliverScore();
        String descriptionScore = store.getDescriptionScore();
        if (WebSiteConstant.MEMBER_DISTRIBUTOR.equals(webSite)) {
            store = storeSiteInfoModel.getStoreByStoreIdAndWebSite(storeId, webSite);
            if (!StringUtils.isEmpty(store.getStoreId())) {
                StoreNameExample storeNameExample = new StoreNameExample();
                storeNameExample.setStoreId(store.getStoreId());
                storeNameExample.setWebSite(webSite);
                StoreName storeName = storeNameModel.getStoreNameByExample(storeNameExample);
                store.setStoreName(storeName != null ? storeName.getStoreName() : null);
                store.setState(state);
                store.setServiceScore(serviceScore);
                store.setDeliverScore(deliverScore);
                store.setDescriptionScore(descriptionScore);
            }
        }
        if (store.getState() != StoreConst.STORE_STATE_OPEN) {
            throw new MallException("店铺已关闭", ResponseConst.STATE_STORE_CLOSE);
        }
        if (store.getBusinessState() == StoreConst.STORE_BUSINESS_STATE_DECORATION) {
            throw new MallException("店铺装修筹备中", ResponseConst.STATE_STORE_BUSINESS_STATE_DECORATION);
        }
        if (store.getBusinessState() == StoreConst.STORE_BUSINESS_STATE_CLOSE) {
            throw new MallException("店铺暂停营业", ResponseConst.STATE_STORE_BUSINESS_STATE_CLOSE);
        }
        //默认店铺logo
        if (StringUtil.isEmpty(store.getStoreLogo())) {
            store.setStoreLogo(stringRedisTemplate.opsForValue().get("default_image_store_logo"));
        }
        //默认店铺背景图片(取移动端横幅)
        if (StringUtil.isEmpty(store.getStoreBannerMobile())) {
            store.setStoreBannerMobile(stringRedisTemplate.opsForValue().get("default_image_store_backdrop"));
        }
        //默认pc端店铺横幅
        if (StringUtils.isEmpty(store.getStoreBannerPc())) {
            store.setStoreBannerPcSource("platform");
            store.setStoreBannerPc(stringRedisTemplate.opsForValue().get("default_image_store_banner_pc"));
        }else{
            store.setStoreBannerPcSource("store");
        }
        FrontStoreVO vo = new FrontStoreVO(store);
        //公司名称
        VendorExample vendorExample = new VendorExample();
        vendorExample.setStoreId(storeId);
        vendorExample.setIsStoreAdmin(VendorConst.IS_STORE_ADMIN_1);
        Vendor vendor = vendorModel.getVendorList(vendorExample, null).get(0);
        StoreCertificateExample storeCertificateExample = new StoreCertificateExample();
        storeCertificateExample.setVendorId(vendor.getVendorId());
        List<StoreCertificate> storeCertificateOldList= storeCertificateModel.getStoreCertificateList(storeCertificateExample, null);
        if(!CollectionUtils.isEmpty(storeCertificateOldList)){
            StoreCertificate storeCertificate = storeCertificateOldList.get(0);
            if (!StringUtil.isEmpty(storeCertificate.getCompanyName())) {
                vo.setCompanyName(storeCertificate.getCompanyName());
            }
        }

        //店铺荣誉资质信息(区别于上面的StoreCertificate老表)
        List<StoreCertificateList> storeCertificateList = storeCertificateNewListModel.getStoreCertificateByStoreId(storeId, webSite);
        vo.setStoreCertificateList(storeCertificateList);

        //店铺简介图片信息
        List<StoreProfileList> storeProfileList = storeProfileModel.getStoreProfileByStoreIdAndStatus(storeId, webSite);
        vo.setStoreProfileList(storeProfileList);
        //店铺简介的内容信息
        StoreProfileTextList storeProfileTextList = storeProfileTextListModel.getList(storeId, webSite);
        vo.setStoreProfileTextList(storeProfileTextList);

        //店铺工厂图片信息
        List<StoreCompanyShowList> storeCompanyShowList = sellerStoreCompanyShowModel.getStoreCompanyShowByStoreIdAndStatus(storeId, webSite);
        vo.setStoreCompanyShowList(storeCompanyShowList);

        //seo
        SysSeoVO sysSeoVO = storeModel.getRecordByTargetIdAndTypeForStoreDetail(storeId, SeoTypeConstant.SEO_TYPE_SHOP, webSite);
        vo.setSeoInfo(sysSeoVO);

        //店铺二维码
        String codeUrl = DomainUrlUtil.SLD_H5_URL + "/standard/store/shopHomePage?vid=" + storeId;
        String qrCode = storeQrCode(codeUrl);
        vo.setStoreQRCode(qrCode);
        vo.setShareLink(codeUrl);

        //会员是否收藏
        if (!StringUtil.isNullOrZero(member.getMemberId())) {
            MemberFollowStoreExample example = new MemberFollowStoreExample();
            example.setMemberId(member.getMemberId());
            example.setStoreId(store.getStoreId());
            List<MemberFollowStore> memberFollowStoreList = memberFollowStoreModel.getMemberFollowStoreList(example, null);
            if (!CollectionUtils.isEmpty(memberFollowStoreList)) {
                vo.setIsFollow("true");
            } else {
                vo.setIsFollow("false");
            }
        } else {
            vo.setIsFollow("false");
        }
        return SldResponse.success(vo);
    }

    @ApiOperation("获取店铺内部商品分类接口")
    @OperationLogger(option = "获取店铺内部商品分类接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "storeId", value = "店铺id", required = true)
    })
    @GetMapping("storeCategory")
    public JsonResult<Object> storeCategory(HttpServletRequest request, @RequestParam("storeId") Long storeId) {
        String webSite = WebUtil.getWebSite(request);
        PagerInfo pager = WebUtil.handlerPagerInfo(request);
        List<StoreCategoryTreeVO> tree = new ArrayList<>();
        StoreInnerLabelExample storeInnerLabelExample = new StoreInnerLabelExample();
        storeInnerLabelExample.setWebSite(webSite);
        storeInnerLabelExample.setParentInnerLabelId(0);
        storeInnerLabelExample.setStoreId(storeId);
        storeInnerLabelExample.setOrderBy("inner_label_sort ASC");
        storeInnerLabelExample.setIsShow(StoreCateConst.STORE_LABEL_IS_SHOW);
        List<StoreInnerLabel> storeInnerLabelList = storeInnerLabelModel.getStoreInnerLabelList(storeInnerLabelExample, pager);
        generateTree(tree, storeInnerLabelList, 2, webSite);

        return SldResponse.success(tree);
    }

    /**
     * 递归生成树
     *
     * @param treeList treeList
     * @param data     data
     * @return 返回列表
     */
    private List<StoreCategoryTreeVO> generateTree(List<StoreCategoryTreeVO> treeList, List<StoreInnerLabel> data, Integer grade, String webSite) {
        if (grade > 0) {
            for (StoreInnerLabel storeInnerLabel : data) {
                StoreCategoryTreeVO tree = new StoreCategoryTreeVO();
                tree.setInnerLabelId(storeInnerLabel.getInnerLabelId());
                tree.setInnerLabelName(storeInnerLabel.getInnerLabelName());
                tree.setInnerLabelSort(storeInnerLabel.getInnerLabelSort());
                tree.setIsShow(storeInnerLabel.getIsShow());
                tree.setParentInnerLabelId(storeInnerLabel.getParentInnerLabelId());
                tree.setCreateTime(storeInnerLabel.getCreateTime());
                tree.setUpdateTime(storeInnerLabel.getUpdateTime());


                StoreInnerLabelExample storeInnerLabelExample = new StoreInnerLabelExample();
                storeInnerLabelExample.setWebSite(webSite);
                storeInnerLabelExample.setParentInnerLabelId(storeInnerLabel.getInnerLabelId());
                storeInnerLabelExample.setIsShow(StoreCateConst.STORE_LABEL_IS_SHOW);
                storeInnerLabelExample.setOrderBy("inner_label_sort ASC");
                tree.setChildren(generateTree(new ArrayList<>(),
                        storeInnerLabelModel.getStoreInnerLabelList(storeInnerLabelExample, null), grade - 1,webSite));
                SysSeoVO sysSeoVO = storeModel.getRecordByTargetIdAndTypeForStoreDetail(Integer.valueOf(tree.getInnerLabelId()).longValue(),
                        SeoTypeConstant.SEO_TYPE_SHOP_CATEGORY,webSite);
                tree.setSeoInfo(sysSeoVO);

                treeList.add(tree);
            }
        }
        return treeList;
    }

    /**
     * 生成店铺二维码
     *
     * @param codeUrl 店铺url地址
     * @return 店铺二维码
     * @throws IOException     异常
     * @throws WriterException 异常
     */
    private String storeQrCode(String codeUrl) throws IOException, WriterException {

        //将图片转化成base64进行输出
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        Map<EncodeHintType, String> hints = new HashMap<>(16);
        // 内容所使用编码
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        BitMatrix bitMatrix = new MultiFormatWriter().encode(codeUrl, BarcodeFormat.QR_CODE, 300,
                300, hints);
        // 生成二维码
        String codeImg;
        MatrixToImageWriter.writeToStream(bitMatrix, "jpg", byteArrayOutputStream);
        codeImg = new String(Base64.encodeBase64(byteArrayOutputStream.toByteArray()));
        return codeImg;
    }

}
