package com.qs.mp.web.controller.api.admin;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qs.mp.channel.domain.Channel;
import com.qs.mp.channel.domain.param.ChannelParam;
import com.qs.mp.channel.domain.vo.ChannelOperDataVO;
import com.qs.mp.channel.domain.vo.ChannelVO;
import com.qs.mp.channel.service.IChannelOrderService;
import com.qs.mp.channel.service.IChannelService;
import com.qs.mp.channel.service.IChannelUserRelService;
import com.qs.mp.common.annotation.Log;
import com.qs.mp.common.constant.UserConstants;
import com.qs.mp.common.core.domain.AjaxResult;
import com.qs.mp.common.core.page.TableDataInfo;
import com.qs.mp.common.enums.BusinessType;
import com.qs.mp.common.enums.ChannelRoleEnum;
import com.qs.mp.common.enums.ErrorCodeEnum;
import com.qs.mp.system.service.ISysUserService;
import com.qs.mp.user.service.IUserTicketOrderService;
import com.qs.mp.web.controller.common.BaseApiController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import ma.glasnost.orika.MapperFacade;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @auther zhongcp
 * @create 2022-02-28 16:17:48
 * @describe 渠道管理前端控制器
 */
@Api("渠道管理API")
@RestController
@RequestMapping("/api/v1/mp/admin/channel/*")
@Component
public class ChannelMgrController extends BaseApiController {

	@Autowired
	private IChannelService channelService;

	@Autowired
	private IChannelUserRelService channelUserRelService;

	@Autowired
	private IChannelOrderService channelOrderService;

	@Autowired
	private IUserTicketOrderService userTicketOrderService;

	@Autowired
	private ISysUserService userService;

	@Autowired
	private MapperFacade mapperFacade;

	/**
	 * 获取我的下级渠道列表信息，LIMIT 50
	 *
	 * @return
	 */
	@PostMapping("/tree")
	@PreAuthorize("@ss.hasPermi('business:channel:list')")
	public AjaxResult treeChannel(@RequestBody Channel channel) {
		List<ChannelVO> list = new ArrayList<ChannelVO>();
		QueryWrapper<Channel> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("t1.parent_id", null!=channel && null != channel.getParentId()?channel.getParentId():0);
		queryWrapper.gt("t1.level", 0);
		queryWrapper.likeRight(null != channel && StringUtils.isNotBlank(channel.getMobile()), "t1.mobile", channel.getMobile());
		queryWrapper.likeRight(null != channel && StringUtils.isNotBlank(channel.getName()), "t1.name", channel.getName());
		queryWrapper.orderByAsc("t1.level").orderByDesc("t1.channel_id");
		queryWrapper.last("limit 50");
		list = channelService.selectChannelVoList(queryWrapper);
		if(null != list && list.size() > 0) {
			for(ChannelVO channelVO : list) {
				if(null != channelVO && StringUtils.isNotBlank(channelVO.getChannelNo())) {
//					int siteCnt = channelService.getChannelSiteCnt(channelVO.getChannelNo());
//					int userCnt = channelUserRelService.getChannelUserCnt(channelVO.getChannelNo());
//					channelVO.setSiteCnt(siteCnt);
//					channelVO.setUserCnt(userCnt);
					// 查询子渠道数量
					int childCnt = channelService.count(
							new LambdaQueryWrapper<Channel>().eq(Channel::getParentId, channelVO.getChannelId())
							.gt(Channel::getLevel, 0));
					channelVO.setChildCnt(childCnt);
				}
			}
		}
		return AjaxResult.success(list);
	}


	/**
	 * 查询所有渠道列表
	 *
	 * @return
	 */
	@PostMapping("/listAll")
	@PreAuthorize("@ss.hasPermi('business:channel:list')")
	public AjaxResult listAllChannel() {
		List<Channel> list = new ArrayList<Channel>();
		LambdaQueryWrapper<Channel> queryWrapper = new LambdaQueryWrapper<Channel>();
		queryWrapper.gt(Channel::getLevel, 0);
		queryWrapper.orderByAsc(Channel::getLevel).orderByDesc(Channel::getChannelId);
		list = channelService.list(queryWrapper);
		return AjaxResult.success(list);
	}


	/**
	 * 获取我的下级渠道列表信息，支持翻页
	 *
	 * @return
	 */
	@PostMapping("/list")
	@PreAuthorize("@ss.hasPermi('business:channel:list')")
	public TableDataInfo listChannel(@RequestBody ChannelVO channel) {
		List<ChannelVO> list = new ArrayList<ChannelVO>();
		startPage();
		QueryWrapper<Channel> queryWrapper = new QueryWrapper<>();
		if(null!=channel && null != channel.getParentId()) {
			queryWrapper.eq("t1.parent_id", channel.getParentId());
		}
		queryWrapper.gt("t1.level", 0);
		queryWrapper.eq(null != channel && null != channel.getLevel(),"t1.level", channel.getLevel());
		queryWrapper.likeRight(null != channel && StringUtils.isNotBlank(channel.getMobile()), "t1.mobile", channel.getMobile());
		queryWrapper.likeRight(null != channel && StringUtils.isNotBlank(channel.getName()), "t1.name", channel.getName());
		queryWrapper.likeRight(null != channel && StringUtils.isNotBlank(channel.getParentName()), "t2.name", channel.getParentName());
		queryWrapper.eq(null != channel && null != channel.getProvinceId(), "t1.province_id", channel.getProvinceId());
		queryWrapper.eq(null != channel && null != channel.getCityId(), "t1.city_id", channel.getCityId());
		queryWrapper.eq(null != channel && null != channel.getAreaId(), "t1.area_id", channel.getAreaId());
		list = channelService.selectChannelList(queryWrapper);
		return getDataTable(list);
	}


	/**
	 * 渠道管理新增一级渠道信息
	 * @param
	 * @return
	 */
	@Log(title = "新增渠道", businessType = BusinessType.INSERT)
	@ApiOperation(value = "新增子渠道信息", notes = "渠道端新增子渠道")
	@PostMapping("/create")
	@PreAuthorize("@ss.hasPermi('business:channel:add')")
	public AjaxResult channelCreate(@Validated @RequestBody ChannelParam channelParam) {
		if (channelParam.getChannelId() != null && channelParam.getChannelId() != 0) {
			return AjaxResult.error("该渠道已存在");
		}
		Channel channel = mapperFacade.map(channelParam, Channel.class);
		// 1、校验名称是否重复、手机号是否存在（渠道表）
		LambdaQueryWrapper<Channel> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(Channel::getName, channel.getName());
		queryWrapper.gt(Channel::getLevel, 0);
		int nameCount = channelService.count(queryWrapper);
		if(nameCount > 0) {
			return AjaxResult.error("渠道名称" + channel.getName() + "已存在！");
		}
		int mobileCount = channelService.count(
		        new LambdaQueryWrapper<Channel>().eq(Channel::getMobile, channel.getMobile()));
		if(mobileCount > 0) {
			 return AjaxResult.error("手机号码" + channel.getMobile() + "已注册！");
		}
		// 2.校验佣金比例，不能高于其父渠道的佣金比例
//		if(null != channel.getParentId() && channel.getParentId() != 0) {
//			Channel parentChannel = channelService.getById(channel.getParentId());
//			if(null != parentChannel) {
//				 if(null != parentChannel.getCommRate()
//						 && channel.getCommRate().compareTo(parentChannel.getCommRate()) > 0) {
//					 return AjaxResult.error("佣金比例不能高于父渠道的佣金比例");
//				 }
//				 channel.setLevel(parentChannel.getLevel()+1);
//				 channel.setChannelNo(parentChannel.getChannelNo()+".");
//			}else {
//				return AjaxResult.error("父渠道不存在");
//			}
//		}else {
//			channel.setLevel(1);
//			channel.setChannelNo("");
//		}
		channel.setParentId(0L);
		channel.setLevel(1);
		channel.setChannelNo("");
		// 3.插入数据
		try {
			channelService.saveChannel(channel,ChannelRoleEnum.CHANNEL);
		} catch (Exception e) {
			return AjaxResult.error("渠道'" + channel.getName() + "'新增失败" + e.getMessage());
		}

		return AjaxResult.success("渠道'" + channel.getName() + "'新增成功");
	}

	/**
	 * 编辑一级子渠道信息
	 * @param
	 * @return
	 */
	@Log(title = "修改渠道", businessType = BusinessType.UPDATE)
	@ApiOperation(value = "编辑子渠道信息", notes = "渠道端编辑子渠道")
	@PostMapping("/update")
	@PreAuthorize("@ss.hasPermi('business:channel:edit')")
	public AjaxResult channelUpdate(@Validated @RequestBody ChannelParam channelParam) {
		if (null == channelParam || null == channelParam.getChannelId()) {
			return error(ErrorCodeEnum.ERROR_CODE_1001);
		}
		Channel channel = mapperFacade.map(channelParam, Channel.class);
		// 1、校验修改子渠道是否为当前用户的子渠道
		Channel oldChannel = channelService.getById(channel.getChannelId());
		if(null == oldChannel || null == oldChannel.getChannelId()) {
			return AjaxResult.error("渠道'" + oldChannel.getName() + "'编辑失败，渠道ID异常");
		}
		// 2.校验名称是否重复、手机号是否存在（渠道表）；
		if(!channel.getName().equals(oldChannel.getName())) {
			LambdaQueryWrapper<Channel> queryWrapper = new LambdaQueryWrapper<>();
			queryWrapper.eq(Channel::getName, channel.getName());
			queryWrapper.gt(Channel::getLevel, 0);
			int nameCount = channelService.count(queryWrapper);
			if(nameCount > 0) {
				return AjaxResult.error("渠道名称" + channel.getName() + "已存在！");
			}
		}
		boolean mobileChange = false;  // 手机号码是否有变更
		if(!channel.getMobile().equals(oldChannel.getMobile())) {

			int mobileCount = channelService.count(
			        new LambdaQueryWrapper<Channel>().eq(Channel::getMobile, channel.getMobile()));
			if(mobileCount > 0) {
				return AjaxResult.error("手机号码" + channel.getMobile() + "已注册！");
			}
			if(UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(channel.getMobile()))) {
				return AjaxResult.error("手机号码" + channel.getMobile() + "已注册！");
			}
			mobileChange = true;
		}
		// 3.校验佣金比例，不能高于其父渠道的佣金比例，不能低于其子渠道的最大佣金比例
//		Channel parentChannel = channelService.getById(oldChannel.getParentId());
//		if(null != parentChannel) {
//			 if(null != parentChannel.getCommRate()
//					 && channel.getCommRate().compareTo(parentChannel.getCommRate()) > 0) {
//				 return AjaxResult.error("佣金比例不能高于父渠道的佣金比例");
//			 }
//			 channel.setLevel(parentChannel.getLevel()+1);
//			 channel.setChannelNo(parentChannel.getChannelNo()+".");
//		}else {
//			return AjaxResult.error("父渠道不存在");
//		}
		// 查询子渠道的最大佣金比例
		QueryWrapper<Channel> queryWrapper = new QueryWrapper<Channel>();
		queryWrapper.select("IFNULL(max(comm_rate),0) as commRate");
		queryWrapper.lambda().eq(Channel::getParentId, channel.getChannelId());
		Map<String, Object> map = channelService.getMap(queryWrapper);
		if(null != map && map.containsKey("commRate")) {
			BigDecimal commRate = new BigDecimal(map.get("commRate").toString());
			if(!commRate.equals(BigDecimal.ZERO) && channel.getCommRate().compareTo(commRate) < 0) {
				return AjaxResult.error("不能低于其子渠道的最大佣金比例");
			}
		}
		try {
			channel.setUserId(oldChannel.getUserId());
			channelService.updateChannel(channel, mobileChange);
		} catch (Exception e) {
			return AjaxResult.error(e.getMessage());
		}
		return AjaxResult.success("渠道'" + channel.getName() + "'编辑成功");
	}


	/**
	 * 停用、启用渠道
	 * @param
	 * @return
	 */
	@Log(title = "启停渠道", businessType = BusinessType.UPDATE)
	@ApiOperation(value = "停用、启用渠道信息", notes = "渠道管理编辑子渠道")
	@PostMapping("/status")
	@PreAuthorize("@ss.hasPermi('business:channel:edit')")
	public AjaxResult channelStatus(@RequestBody JSONObject jsonObject) {
		String channelId = jsonObject.containsKey("channelId")?jsonObject.get("channelId").toString():"";
		String status = jsonObject.containsKey("status")?jsonObject.get("status").toString():"";
		if (null == jsonObject || StringUtils.isBlank(channelId)
				|| StringUtils.isBlank(status)) {
			return error(ErrorCodeEnum.ERROR_CODE_1001);
		}
		try {
			channelService.lambdaUpdate().set(Channel::getStatus, status).eq(Channel::getChannelId, channelId).update();
		} catch (Exception e) {
			return AjaxResult.error("操作失败");
		}
		return AjaxResult.success("操作成功");
	}


	/**
	 * 查询渠道详情
	 * @param
	 * @return
	 */
	@ApiOperation(value = "查询渠道详情信息", notes = "渠道管理编辑子渠道查询渠道详情")
	@PostMapping("/detail")
	@PreAuthorize("@ss.hasPermi('business:channel:query')")
	public AjaxResult getChannelDetail(@RequestBody JSONObject jsonObject) {
		String channelId = (null != jsonObject && jsonObject.containsKey("channelId"))?jsonObject.getString("channelId"):"";
		if (StringUtils.isBlank(channelId)) {
			return error(ErrorCodeEnum.ERROR_CODE_1001);
		}
		ChannelVO channelVO = channelService.getChannelVoById(Long.valueOf(channelId));
		if(null == channelVO || null == channelVO.getChannelId()) {
			 return error(ErrorCodeEnum.ERROR_CODE_1001);
		}
		if(null != channelVO && StringUtils.isNotBlank(channelVO.getChannelNo())) {
			int siteCnt = channelService.getChannelSiteCnt(channelVO.getChannelNo());
			int userCnt = channelUserRelService.getChannelTotalUserCnt(channelVO.getChannelNo());
			channelVO.setSiteCnt(siteCnt);
			channelVO.setUserCnt(userCnt);
			channelVO.setParentsName(getParentsName(channelVO.getChannelNo()));
		}
	    // 查询渠道销售额、佣金收入、订单数等
	    ChannelOperDataVO channelOperDataVO = channelService.getChannelTotalOperData(channelVO.getChannelNo());
		// LambdaQueryWrapper<ChannelOrder> queryWrapper = new LambdaQueryWrapper<ChannelOrder>();
		//queryWrapper.eq(ChannelOrder::getChannelId, channelId);
		//int orderCnt = channelOrderService.count(queryWrapper);
		//channelOperDataVO.setOrderCnt(orderCnt);

		// 盲票销量
		int ticketSaleCnt = userTicketOrderService.getChannelTotalTicketNumCnt(channelVO.getChannelNo());
		channelOperDataVO.setTicketSaleCnt(ticketSaleCnt);
	    channelVO.setOperData(channelOperDataVO);
		return AjaxResult.success(channelVO);
	}


	// 获取上级渠道迭代
	private String getParentsName(String channelNo) {
		if(StringUtils.isNotBlank(channelNo)) {
			String[] noArray = channelNo.split("\\.");
			if(null != noArray && noArray.length > 0) {
				List<String> noList = new ArrayList<String>();
				String parentNo = "";
				for (int i = 0; i < noArray.length; i++) {
					if(null != noArray[i] && StringUtils.isNotBlank(noArray[i])) {
						parentNo += (i>0?".":"")+noArray[i];
						if(StringUtils.isNotBlank(parentNo) && !parentNo.equals(channelNo)) {
							noList.add(parentNo);
						}
					}
				}
				if(noList.size() > 0 ) {
					LambdaQueryWrapper<Channel> queryWrapper = new LambdaQueryWrapper<Channel>();
					queryWrapper.gt(Channel::getLevel, 0);
					queryWrapper.in(Channel::getChannelNo,noList);
					queryWrapper.orderByAsc(Channel::getLevel);
					List<Channel> list = channelService.list(queryWrapper);
					if(null != list && list.size() >0) {
						String names = list.stream().map(Channel::getName).collect(Collectors.joining(" > "));
						return names;
					}
				}
			}
		}
		return "";
	}

}
