/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.api.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import org.springblade.common.cache.ParamCache;
import org.springblade.common.constant.CommonConstant;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.support.Kv;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.modules.api.response.IndexResponse;
import org.springblade.modules.api.service.IApiService;
import org.springblade.modules.desk.entity.Notice;
import org.springblade.modules.desk.service.INoticeService;
import org.springblade.modules.desk.wrapper.NoticeWrapper;
import org.springblade.modules.platform.entity.Freight;
import org.springblade.modules.platform.entity.UserAddress;
import org.springblade.modules.platform.service.IAdsService;
import org.springblade.modules.platform.service.IFreightService;
import org.springblade.modules.platform.service.IUserAddressService;
import org.springblade.modules.platform.service.IUserBrowseService;
import org.springblade.modules.platform.vo.UserAddressVO;
import org.springblade.modules.platform.wrapper.UserAddressWrapper;
import org.springblade.modules.shopping.entity.Consign;
import org.springblade.modules.shopping.entity.Goods;
import org.springblade.modules.shopping.entity.GoodsAttributes;
import org.springblade.modules.shopping.entity.GoodsSpecs;
import org.springblade.modules.shopping.service.*;
import org.springblade.modules.shopping.vo.ConsignVO;
import org.springblade.modules.shopping.vo.GoodsAttributesVO;
import org.springblade.modules.shopping.vo.GoodsVO;
import org.springblade.modules.shopping.vo.SpecCatsVO;
import org.springblade.modules.shopping.wrapper.GoodsAttributesWrapper;
import org.springblade.modules.shopping.wrapper.GoodsWrapper;
import org.springblade.modules.system.entity.Region;
import org.springblade.modules.system.service.IRegionService;
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 java.util.List;

/**
 * 控制器
 *
 * @author xuwei
 * @since 2022-02-12
 */
@RestController
@AllArgsConstructor
@RequestMapping(CommonConstant.API_URL)
@Api(value = "首页", tags = "02.首页接口")
public class Api02Controller extends BladeController {

	private final IGoodsService goodsService;
	private final IUserBrowseService userBrowseService;
	private final ISpecCatsService specCatsService;
	private final IGoodsSpecsService goodsSpecsService;
	private final IGoodsAttributesService goodsAttributesService;
	private final IConsignConfigService consignConfigService;
	private final INoticeService noticeService;
	private final IConsignService consignService;
	private final IAdsService adsService;
	private final IRegionService regionService;
	private final IFreightService freightService;
	private final IApiService apiService;
	private final IUserAddressService userAddressService;

	/**
	 * 首页
	 */
	@GetMapping("/index-data")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "首页接口", notes = "用户ID，可不传")
	public R<IndexResponse> indexResponse(@ApiParam(value = "用户ID", required = false) @RequestParam(required = false) String userId) {
		IndexResponse response = new IndexResponse();
		Integer limit = Integer.valueOf(ParamCache.getValue(CommonConstant.DEFAULT_ADS_LIMIT));
		response.setBanners(adsService.selectAdsList(1, limit));
		List<Notice> notices = noticeService.list(Wrappers.<Notice>lambdaQuery()
			.eq(Notice::getStatus, 1)
			.eq(Notice::getCategory, 6)
			.orderByDesc(Notice::getUpdateTime));
		response.setNotices(NoticeWrapper.build().listVO(notices));
		List<Goods> list = goodsService.list(Wrappers.<Goods>lambdaQuery()
				.eq(Goods::getIsSale, 2)
				.eq(Goods::getIsTicket, 2)
				.orderByAsc(Goods::getSort)
			.last(" limit 6"));
		response.setGoodsTicket(list);
		Kv kv = consignConfigService.selectCacheConsignConfig();
		List<ConsignVO> consignList = consignService.selectConsignList(kv.getLong("id"));
		response.setConsigns(consignList);
		response.setStartTime(kv.getStr("startTime"));
		response.setEndTime(kv.getStr("endTime"));
		return R.data(response);
	}

	@GetMapping("/goods-detailById")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "商品详情", notes = "传入商品ID和用户ID，包含商品基本信息、商品规格项、商品参数")
	public R<GoodsVO> goodsDetailById(@ApiParam(value = "商品ID", required = true) @RequestParam(required = true) Long goodsId,
									  @ApiParam(value = "用户ID", required = false) @RequestParam(required = false) Long userId) {
		Goods goods = goodsService.getById(goodsId);
		if (goods == null){
			return R.fail("数据不存在！");
		}
		GoodsVO vo = GoodsWrapper.build().entityVO(goods);
		List<GoodsAttributes> attList = goodsAttributesService.list(Wrappers.<GoodsAttributes>lambdaQuery().eq(GoodsAttributes::getGoodsId, goodsId));
		//商品参数
		vo.setGoodsAttributes(GoodsAttributesWrapper.build().listVO(attList));
		//商品规格项和值
		vo.setSpecItems(apiService.specItemsList(goodsId));
		if (userId != null){
			//浏览记录
			userBrowseService.userBrowse(userId,goodsId);
		}
		return R.data(vo);
	}

	@GetMapping("/goodsSpecItem-list")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "获取商品规格项", notes = "传入商品Id和分类ID")
	public R<List<SpecCatsVO>> goodsSpecItemList(@ApiParam(value = "商品Id", required = true) @RequestParam Long goodsId,
												 @ApiParam(value = "分类Id", required = true) @RequestParam Long catId) {
		return R.data(specCatsService.selectSpecItems(goodsId,catId));
	}

	@GetMapping("/goodsSpec-detailBySpecId")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "选取规格获取商品价格等信息", notes = "传入规格Id字符串")
	public R<GoodsSpecs> goodsSpecsDetailBySpecId(@ApiParam(value = "规格Id字符串", required = true) @RequestParam String specIds) {
		GoodsSpecs goodsSpecs = goodsSpecsService.getOne(Wrappers.<GoodsSpecs>lambdaQuery().eq(GoodsSpecs::getSpecIds,specIds));
		return R.data(goodsSpecs);
	}

	@GetMapping("/goodsAttributes-detailByGoodsId")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "查询商品参数", notes = "传入商品ID")
	public R<List<GoodsAttributesVO>> goodsAttributesDetailByGoodsId(@ApiParam(value = "商品ID", required = true) @RequestParam String goodsId) {
		List<GoodsAttributes> list = goodsAttributesService.list(Wrappers.<GoodsAttributes>lambdaQuery().eq(GoodsAttributes::getGoodsId, goodsId));
		return R.data(GoodsAttributesWrapper.build().listVO(list));
	}

	@GetMapping("/userAddress-detailByIdAndFreight")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "获取用户地址详情（包含运费）", notes = "传入地址ID")
	public R<UserAddressVO> userAddressAndFreightById(@ApiParam(value = "地址ID", required = true) @RequestParam Long id) {
		UserAddress userAddress = userAddressService.getById(id);
		if(userAddress == null){
			return R.fail("数据不存在");
		}
		UserAddressVO vo = UserAddressWrapper.build().entityVO(userAddress);
		vo.setWlPrice(0D);
		if(userAddress.getDistrictCode() != null){
			Region region = regionService.getById(userAddress.getDistrictCode());
			if (region != null){
				Freight freight = freightService.getOne(Wrappers.<Freight>lambdaQuery().eq(Freight::getCode, region.getProvinceCode()));
				if (freight != null){
					vo.setWlPrice(freight.getFreight());
				}
			}
		}
		return R.data(vo);
	}

}
