/*
 * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
 *
 * https://www.gz-yami.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.yami.shop.multishop.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.dto.ListRelatedProductsDto;
import com.yami.shop.bean.dto.ListUnRelatedProductsDTO;
import com.yami.shop.bean.dto.RelatedProductsDTO;
import com.yami.shop.bean.enums.*;
import com.yami.shop.bean.event.ProdChangeEvent;
import com.yami.shop.bean.event.ProdChangeStatusEvent;
import com.yami.shop.bean.model.*;
import com.yami.shop.bean.param.OfflineHandleEventAuditParam;
import com.yami.shop.bean.param.ProductExportParam;
import com.yami.shop.bean.param.ProductParam;
import com.yami.shop.common.exception.GlobalException;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.util.Json;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.security.multishop.util.SecurityUtils;
import com.yami.shop.service.*;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import ma.glasnost.orika.MapperFacade;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.*;


/**
 * 多商户商品信息管理实现
 *
 * @author lgh
 * @version 1.0.0
 * @since 2018-11-26
 */
@Controller
@RequestMapping("/prod/prod")
public class ProductController {

    @Autowired
    private ProductService productService;

    @Autowired
    private MapperFacade mapperFacade;

    @Autowired
    private SkuService skuService;

    @Autowired
    private BasketService basketService;

    @Autowired
    private BrandService brandService;

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private OfflineHandleEventService offlineHandleEventService;

    @Autowired
    private ShopDetailService shopDetailService;

    @Autowired
    private CategoryService categoryService;

    /**
     * 分页获取商品信息
     */
    @GetMapping("/page")
    public ResponseEntity<IPage<Product>> page(ProductParam product, PageParam<Product> page) {
        IPage<Product> products = productService.page(page,
                new LambdaQueryWrapper<Product>()
                        .like(StrUtil.isNotBlank(product.getProdName()), Product::getProdName, product.getProdName())
                        .eq(Product::getShopId, SecurityUtils.getShopUser().getShopId())
                        .eq(product.getStatus() != null, Product::getStatus, product.getStatus())
                        .eq(product.getShopCategoryId() != null, Product::getShopCategoryId, product.getShopCategoryId())
                        .like(StrUtil.isNotBlank(product.getProdName()), Product::getProdName, product.getProdName())
                        .ne(Product::getStatus, -1)
                        .orderByDesc(Product::getPutawayTime));
        return ResponseEntity.ok(products);
    }

    /**
     * 分页获取上架的商品信息
     */
    @GetMapping("/pageOnLineProd")
    public ResponseEntity<IPage<Product>> pageOnLineProd(ProductParam product, PageParam<Product> page) {
//        IPage<Product> products = productService.page(page,
//                new LambdaQueryWrapper<Product>()
//                        .eq(Product::getShopId, SecurityUtils.getShopUser().getShopId())
//                        .eq(Product::getStatus, 1)
//                        .like(StrUtil.isNotBlank(product.getProdName()),Product::getProdName,product.getProdName())
//                        .eq(Objects.nonNull(product.getShopCategoryId()),Product::getShopCategoryId, product.getShopCategoryId())
//                        .orderByDesc(Product::getPutawayTime));
        product.setShopId(SecurityUtils.getShopUser().getShopId());
        IPage<Product> products = productService.pageProducts(page,product);
        return ResponseEntity.ok(products);
    }

    /**
     * 获取信息
     */
    @GetMapping("/info/{prodId}")
    public ResponseEntity<Product> info(@PathVariable("prodId") Long prodId) {
        Product prod = productService.getProductByProdId(prodId);
        if (!Objects.equals(prod.getShopId(), SecurityUtils.getShopUser().getShopId())) {
            throw new GlobalException("没有权限获取该商品规格信息");
        }
        Brand brand = brandService.getById(prod.getBrandId());
        if (Objects.nonNull(brand)){
            prod.setBrand(brand);
        }
        List<Sku> skuList = skuService.listByProdId(prodId);
        prod.setSkuList(skuList);

        return ResponseEntity.ok(prod);
    }

    /**
     * 保存
     */
    @PostMapping
    public ResponseEntity<String> save(@Valid @RequestBody ProductParam productParam) {
        checkParam(productParam);
        Long shopId = SecurityUtils.getShopUser().getShopId();
        ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(shopId);
        if (Objects.equals(shopDetail.getShopStatus(), ShopStatus.OFFLINE.value())) {
            throw new GlobalException("店铺违规下线中，不能发布商品，请联系管理员后重试");
        }
        Product product = mapperFacade.map(productParam, Product.class);
        product.setStatus(1);
        product.setDeliveryMode(Json.toJsonString(productParam.getDeliveryModeVo()));
        product.setShopId(shopId);
        product.setUpdateTime(new Date());
        product.setPutawayTime(new Date());
        product.setCreateTime(new Date());
        product.setVersion(0);
        // 商品销量设置为0
        product.setSoldNum(0);
//        product.setGroupActivityId(0L);
//        product.setSeckillActivityId(0L);
        product.setProdType(ProdType.PROD_TYPE_NORMAL.value());
        product.setActivityId(0L);
        productService.saveProduct(product);
        return ResponseEntity.ok().build();
    }

    /**
     * 修改
     */
    @PutMapping
    public ResponseEntity<String> update(@Valid @RequestBody ProductParam productParam) {
        checkParam(productParam);
        Product dbProduct = productService.getProductByProdId(productParam.getProdId());
        if (!Objects.equals(dbProduct.getShopId(), SecurityUtils.getShopUser().getShopId())) {
            return ResponseEntity.badRequest().body("无法修改非本店铺商品信息");
        }
        Long shopId = SecurityUtils.getShopUser().getShopId();
        ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(shopId);
        if (Objects.equals(shopDetail.getShopStatus(), ShopStatus.OFFLINE.value())) {
            throw new GlobalException("店铺违规下线中，不能修改商品，请联系管理员后重试");
        }

        List<Sku> dbSkus = skuService.listByProdId(dbProduct.getProdId());


        Product product = mapperFacade.map(productParam, Product.class);
        product.setDeliveryMode(Json.toJsonString(productParam.getDeliveryModeVo()));
        product.setUpdateTime(new Date());

        dbProduct.setSkuList(dbSkus);
        productService.updateProduct(product, dbProduct);


        List<String> userIds = basketService.listUserIdByProdId(product.getProdId());

        for (String userId : userIds) {
            basketService.removeShopCartItemsCacheByUserId(userId);
        }
        for (Sku sku : dbSkus) {
            skuService.removeSkuCacheBySkuId(sku.getSkuId(), sku.getProdId());
        }
        return ResponseEntity.ok().build();
    }

    /**
     * 删除
     */
    @DeleteMapping("/{prodId}")
    public ResponseEntity<Void> delete(@PathVariable("prodId") Long prodId) {
        Product dbProduct = productService.getProductByProdId(prodId);
        if (!Objects.equals(dbProduct.getShopId(), SecurityUtils.getShopUser().getShopId())) {
            throw new GlobalException("无法获取非本店铺商品信息");
        }
        List<Sku> dbSkus = skuService.listByProdId(dbProduct.getProdId());
        // 删除商品
        productService.removeProductByProdId(prodId);

        for (Sku sku : dbSkus) {
            skuService.removeSkuCacheBySkuId(sku.getSkuId(), sku.getProdId());
        }

        List<String> userIds = basketService.listUserIdByProdId(prodId);

        for (String userId : userIds) {
            basketService.removeShopCartItemsCacheByUserId(userId);
        }
//        删除商品时，改变分销设置,团购订单处理。。。
        applicationContext.publishEvent(new ProdChangeEvent(dbProduct));
        return ResponseEntity.ok().build();
    }


    /**
     * 更新商品状态
     */
    @PutMapping("/prodStatus")
    public ResponseEntity<Void> shopStatus(@RequestBody ProductParam productParam) {
        Long prodId = productParam.getProdId();
        Integer prodStatus = productParam.getStatus();
        Product dbProduct = productService.getProductByProdId(prodId);
        if (!Objects.equals(dbProduct.getShopId(), SecurityUtils.getShopUser().getShopId())) {
            throw new GlobalException("无法获取非本店铺商品信息");
        }
        if (!(Objects.equals(dbProduct.getStatus(), ProdStatusEnums.NORMAL.getValue())
                || Objects.equals(dbProduct.getStatus(), ProdStatusEnums.SHOP_OFFLINE.getValue()))) {
            throw new GlobalException("商品不在正常状态，修改失败");
        }
        Long shopId = SecurityUtils.getShopUser().getShopId();
        ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(shopId);
        if (Objects.equals(shopDetail.getShopStatus(), ShopStatus.OFFLINE.value())) {
            throw new GlobalException("店铺处于违规下线中，不能修改商品，请联系管理员后重试");
        }

        if(Objects.equals(productParam.getStatus(),1)){
            Category category = categoryService.getById(dbProduct.getCategoryId());
            if (Objects.equals(category.getStatus(), 0)){
                throw new GlobalException("平台分类处于下线中，商品不能上架，请联系管理员后再进行操作");
            }
        }

        Product product = new Product();
        product.setProdId(prodId);
        product.setStatus(prodStatus);
        if (prodStatus == 1) {
            product.setPutawayTime(new Date());
        }
        dbProduct.setStatus(prodStatus);
        // 商品状态改变时的发送事件，让活动下线
        applicationContext.publishEvent(new ProdChangeStatusEvent(dbProduct, dbProduct.getStatus()));

        productService.updateById(product);
        productService.removeProductCacheByProdId(prodId);
        List<String> userIds = basketService.listUserIdByProdId(prodId);

        for (String userId : userIds) {
            basketService.removeShopCartItemsCacheByUserId(userId);
        }
        return ResponseEntity.ok().build();
    }

    /**
     * 违规商品提交审核
     */
    @PostMapping("/auditApply")
    public ResponseEntity<Void> auditApply(@RequestBody OfflineHandleEventAuditParam offlineHandleEventAuditParam) {
        Product product = productService.getProductByProdId(offlineHandleEventAuditParam.getHandleId());
        if (product == null) {
            throw new GlobalException("商品信息不存在");
        }
        productService.auditApply(offlineHandleEventAuditParam.getEventId(), offlineHandleEventAuditParam.getHandleId(), offlineHandleEventAuditParam.getReapplyReason());
        // 移除缓存
        productService.removeProductCacheByProdId(product.getProdId());
        return ResponseEntity.ok().build();
    }

    /**
     * 通过prodId获取最新下线商品的事件
     */
    @GetMapping("/getOfflineHandleEventByProdId/{prodId}")
    public ResponseEntity<OfflineHandleEvent> getByProdId(@PathVariable Long prodId) {
        OfflineHandleEvent offlineHandleEvent = offlineHandleEventService.getProcessingEventByHandleTypeAndHandleId(OfflineHandleEventType.PROD.getValue(), prodId);
        return ResponseEntity.ok(offlineHandleEvent);
    }

    /**
     * 导出商品
     *
     * @param productParam 导出商品筛选条件
     */
    @GetMapping("/exportProd")
    public void exportProd(ProductExportParam productParam, HttpServletResponse response) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        productParam.setShopId(shopId);
        productParam.setStatus(productParam.getStatus() == null ?ProdStatusEnums.NORMAL.getValue():productParam.getStatus());
        productService.exportProd(productParam,response,shopId);
    }

    @GetMapping(value = "/downloadModel")
    @ResponseBody
    public ResponseEntity downloadModel(HttpServletResponse response) {

        productService.downloadModel(response,SecurityUtils.getShopUser().getShopId());
        return ResponseEntity.ok("开始下载模板");
    }


    @ApiOperation(value = "导入文件")
    @RequestMapping(value = "/exportExcel", method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity exportExcel(@RequestParam("excelFile") MultipartFile excelFile) throws Exception {
        if(excelFile == null) {
            throw new GlobalException("网络繁忙，请稍后重试");
        }
        Long shopId = SecurityUtils.getShopUser().getShopId();
        return ResponseEntity.ok(productService.parseFile(excelFile,shopId));
    }

    private void checkParam(ProductParam productParam) {

        Product.DeliveryModeVO deliveryMode = productParam.getDeliveryModeVo();
        boolean hasDeliverMode = deliveryMode != null
                && (deliveryMode.getHasShopDelivery() || deliveryMode.getHasUserPickUp());
        if (!hasDeliverMode) {
            throw new GlobalException("请选择配送方式");
        }
        List<Sku> skuList = productParam.getSkuList();
        boolean isAllUnUse = true;
        for (Sku sku : skuList) {
            if (sku.getStatus() == 1) {
                isAllUnUse = false;
            }
        }
        if (isAllUnUse) {
            throw new GlobalException("至少要启用一种商品规格");
        }
    }
    /**
     * 根据分类ID查询关联商品
     * */
    @PostMapping("/listRelatedProducts")
    @ApiOperation("根据分类ID查询关联商品")
    public ResponseEntity<IPage<Product>> listRelatedProducts(@RequestBody ListRelatedProductsDto listRelatedProductsDto){
        return ResponseEntity.ok(productService.listRelatedProducts(listRelatedProductsDto));
    }

    /**
     * 取消关联商品
     * */
    @GetMapping("/cancelRelatedProducts/{productId}")
    @ApiOperation("取消关联商品")
    public ResponseEntity<Boolean> cancelRelatedProducts(@PathVariable Long productId){
        Long shopId = SecurityUtils.getShopUser().getShopId();
        return ResponseEntity.ok(productService.cancelRelatedProducts(shopId, productId));
    }

    /**
     * 关联商品
     * */
    @PostMapping("/relatedProducts")
    @ApiOperation("关联商品")
    public ResponseEntity<Boolean> relatedProducts(@RequestBody RelatedProductsDTO relatedProductsDTO){
        Long shopId = SecurityUtils.getShopUser().getShopId();
        return ResponseEntity.ok(productService.relatedProducts(shopId, relatedProductsDTO.getProductId(), relatedProductsDTO.getShopCategoryId()));
    }

    /**
     * 根据商户ID查询未关联商品
     * */
    @PostMapping("/listUnRelatedProducts")
    @ApiOperation("根据商户ID查询未关联商品")
    public ResponseEntity<IPage<Product>> listUnRelatedProducts(@RequestBody ListUnRelatedProductsDTO listUnRelatedProductsDTO){
        return ResponseEntity.ok(productService.listUnRelatedProducts(listUnRelatedProductsDTO));
    }

}
