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.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.qs.mp.admin.domain.excel.ChannelExcel;
import com.qs.mp.admin.domain.excel.UserTicketOrderItemExcel;
import com.qs.mp.admin.domain.vo.TicketCntVO;
import com.qs.mp.admin.service.ITicketService;
import com.qs.mp.channel.domain.Channel;
import com.qs.mp.channel.domain.ChannelOrder;
import com.qs.mp.channel.domain.ChannelOrderDetail;
import com.qs.mp.channel.domain.ChannelUserRel;
import com.qs.mp.channel.domain.param.ChannelParam;
import com.qs.mp.channel.domain.param.SaleSiteEditParam;
import com.qs.mp.channel.domain.param.SaleSiteParam;
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.common.enums.UserTicketOrderStatusEnum;
import com.qs.mp.system.domain.SysUser;
import com.qs.mp.system.service.ISysUserService;
import com.qs.mp.user.domain.UserTicketOrder;
import com.qs.mp.user.service.IUserTicketOrderService;
import com.qs.mp.utils.ExcelUtil;
import com.qs.mp.web.controller.common.BaseApiController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import ma.glasnost.orika.MapperFacade;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
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.util.CollectionUtils;
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(tags = "经销商管理API")
@RestController
@RequestMapping("/api/v1/mp/admin/salesite/*")
public class SaleSiteMgrController extends BaseApiController {

	@Autowired
	private IChannelService channelService;

	@Autowired
	private IChannelUserRelService channelUserRelService;

	@Autowired
	private IChannelOrderService channelOrderService;

	@Autowired
	private IUserTicketOrderService userTicketOrderService;

	@Autowired
	private ISysUserService userService;

	@Autowired
	private ITicketService ticketService;

	@Autowired
	private MapperFacade mapperFacade;


	/**
	 * 获取经销商列表信息，支持翻页
	 *
	 * @return
	 */
	@PostMapping("/list")
	@PreAuthorize("@ss.hasPermi('business:salesite:list')")
	@ApiOperation("获取经销商列表信息，支持翻页")
	@ApiResponses(
			@ApiResponse(code = 200, message = "经销商列表返回信息",response = ChannelVO.class)
	)
	public TableDataInfo listSite(@RequestBody Channel 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.eq("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.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.selectSaleSiteList(queryWrapper);

		if(null != list && list.size() > 0) {
			for(ChannelVO channelVO : list) {
				if(null != channelVO && null != channelVO.getChannelId()
						&& StringUtils.isNotBlank(channelVO.getChannelNo())) {
					// int siteCnt = channelService.getChannelSiteCnt(channelVO.getChannelNo());
					LambdaQueryWrapper<ChannelUserRel> userCntQueryWrapper = new LambdaQueryWrapper<ChannelUserRel>();
					userCntQueryWrapper.eq(ChannelUserRel::getChannelId, channelVO.getChannelId());
					int userCnt = channelUserRelService.count(userCntQueryWrapper);
					channelVO.setUserCnt(userCnt);
					// 查询用户信息
					//SysUser sysUser = userService.selectUserById(channelVO.getUserId());
					// channelVO.setSysUser(sysUser);
					channelVO.setParentsName(getParentsName(channelVO.getChannelNo()));
 				}
			}
		}
		return getDataTable(list);
	}

	// 获取上级渠道迭代
	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 "";
	}

	@PostMapping("/export")
	@PreAuthorize("@ss.hasPermi('business:salesite:export')")
	@ApiOperation("导出经销商信息")
	@ApiResponses(
			@ApiResponse(code = 200, message = "经销商列表返回信息",response = ChannelVO.class)
	)
	public AjaxResult export(@RequestBody Channel channel) {
		QueryWrapper<Channel> queryWrapper = new QueryWrapper<>();
		if(null!=channel && null != channel.getParentId()) {
			queryWrapper.eq("t1.parent_id", channel.getParentId());
		}
		queryWrapper.eq("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.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<ChannelVO> list  = channelService.selectSaleSiteList(queryWrapper);
		if (CollectionUtils.isEmpty(list)) {
			return AjaxResult.error("没有符合条件的经销商信息");
		}

		if(null != list && list.size() > 0) {
			for(ChannelVO channelVO : list) {
				if(null != channelVO && null != channelVO.getChannelId()
						&& StringUtils.isNotBlank(channelVO.getChannelNo())) {
					channelVO.setParentsName(getParentsNameAndCommRate(channelVO.getChannelNo()));
				}
			}
		}

		List<ChannelExcel> excelList = new ArrayList<>();
		for (ChannelVO channelVO : list) {
			ChannelExcel channelExcel = new ChannelExcel();
			channelExcel.setChannelId(channelVO.getChannelId());
			channelExcel.setCommRate(channelVO.getCommRate());
			channelExcel.setName(channelVO.getName());
			channelExcel.setParentsName(channelVO.getParentsName());
			channelExcel.setCreatedTime(channelVO.getCreatedTime());
			channelExcel.setOffLineSaleCnt(channelVO.getOffLineSaleCnt());
			channelExcel.setOffLineQtyCnt(channelVO.getOffLineQtyCnt());
			channelExcel.setOnLineSaleCnt(channelVO.getOnLineSaleCnt());
			channelExcel.setUserCnt(channelVO.getUserCnt());
			if (Objects.nonNull(channelVO.getCertifyStatus())) {
				channelExcel.setCertifyStatus(channelVO.getCertifyStatus().getDesc());
			}
			excelList.add(channelExcel);
		}

		ExcelUtil<ChannelExcel> util = new ExcelUtil<>(ChannelExcel.class);
		return util.exportExcel(excelList, "经销商导出", false);
	}

	private String getParentsNameAndCommRate(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) {
						return list.stream().map(channel -> channel.getName() + "(" + channel.getCommRate() + "%)").collect(Collectors.joining(" > "));
					}
				}
			}
		}
		return "";
	}


	/**
	 * 查询所有渠道列表
	 *
	 * @return
	 */
	@PostMapping("/listAll")
	// @PreAuthorize("@ss.hasPermi('business:salesite:list')")
	@ApiOperation("查询所有渠道列表")
	@ApiResponses(
			@ApiResponse(code = 200, message = "经销商列表返回信息",response = Channel.class)
	)
	public AjaxResult listAllSite() {
		List<Channel> list = new ArrayList<Channel>();
		LambdaQueryWrapper<Channel> queryWrapper = new LambdaQueryWrapper<Channel>();
		queryWrapper.eq(Channel::getLevel, 0);
		queryWrapper.orderByDesc(Channel::getChannelId);
		list = channelService.list(queryWrapper);
		return AjaxResult.success(list);
	}

	/**
	 * 新增经销商信息
	 * @param
	 * @return
	 */
	@Log(title = "新增经销商", businessType = BusinessType.INSERT)
	@ApiOperation(value = "新增经销商信息", notes = "经销商端新增经销商")
	@PostMapping("/create")
	@PreAuthorize("@ss.hasPermi('business:salesite:add')")
	public AjaxResult siteCreate(@Validated @RequestBody SaleSiteParam 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.eq(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("");
		}
		// 3.插入数据
		try {
			channelService.saveChannel(channel,ChannelRoleEnum.SALESITE);
		} catch (Exception e) {
			return AjaxResult.error("经销商'" + channel.getName() + "'新增失败" + e.getMessage());
		}

		return AjaxResult.success("经销商'" + channel.getName() + "'新增成功");
	}

	@PreAuthorize("@ss.hasPermi('business:salesite:edit')")
	@ApiOperation("修改门店信息")
	@PostMapping("/edit")
	public AjaxResult edit(@RequestBody SaleSiteEditParam saleSiteEditParam){
		Channel channel = channelService.getById(saleSiteEditParam.getChannelId());
		if (channel == null) {
			return AjaxResult.error("门店信息不存在");
		}

		boolean rtn = channelService.update(new LambdaUpdateWrapper<Channel>()
			.set(Channel::getName, saleSiteEditParam.getName())
			.eq(Channel::getChannelId, saleSiteEditParam.getChannelId()));

		if (!rtn) {
			return AjaxResult.error("更新门店信息失败");
		}

		return AjaxResult.success();
	}


	/**
	 * 编辑经销商信息
	 * @param
	 * @return
	 */
	@Log(title = "修改经销商", businessType = BusinessType.UPDATE)
	@ApiOperation(value = "编辑经销商信息", notes = "经销商端编辑经销商")
	@PostMapping("/update")
	@PreAuthorize("@ss.hasPermi('business:salesite:edit')")
	public AjaxResult siteUpdate(@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.eq(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("父经销商不存在");
		}
		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:salesite:edit')")
	public AjaxResult siteStatus(@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();
			// 查询经销商信息
//			Channel channel = channelService.getById(channelId);
//			if(null != channel && null != channel.getUserId()) {
//				SysUser sysUser = new SysUser();
//				sysUser.setUserId(channel.getUserId());
//				sysUser.setStatus(status);
//				userService.updateUserStatus(sysUser);
//			}
		} catch (Exception e) {
			return AjaxResult.error("操作失败");
		}
		return AjaxResult.success("操作成功");
	}


	/**
	 * 查询经销商详情
	 * @param
	 * @return
	 */
	@ApiOperation(value = "查询经销商详情信息", notes = "经销商管理编辑子经销商查询经销商详情")
	@PostMapping("/detail")
	@PreAuthorize("@ss.hasPermi('business:salesite:query')")
	public AjaxResult getSiteDetail(@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());
			LambdaQueryWrapper<ChannelUserRel> userCntQueryWrapper = new LambdaQueryWrapper<ChannelUserRel>();
			userCntQueryWrapper.eq(ChannelUserRel::getChannelId, channelVO.getChannelId());
			int userCnt = channelUserRelService.count(userCntQueryWrapper);
			channelVO.setUserCnt(userCnt);
			channelVO.setParentsName(getParentsName(channelVO.getChannelNo()));
		}
	    // 查询经销商销售额、佣金收入、订单数等
	    ChannelOperDataVO channelOperDataVO = channelService.getChannelTotalOperData(channelVO.getChannelNo());

		// 盲票销售张数
		int ticketSaleCnt = userTicketOrderService.getSaleSiteTotalTicketNumCnt(channelVO.getChannelId());
		channelOperDataVO.setTicketSaleCnt(ticketSaleCnt);
	    channelVO.setOperData(channelOperDataVO);

        if(null != channelVO && null != channelVO.getChannelId()) {
	    	LambdaQueryWrapper<ChannelUserRel> userCntQueryWrapper = new LambdaQueryWrapper<ChannelUserRel>();
			userCntQueryWrapper.eq(ChannelUserRel::getChannelId, channelVO.getChannelId());
			int userCnt = channelUserRelService.count(userCntQueryWrapper);
			channelVO.setUserCnt(userCnt);

	    	int ticketQtyCnt = ticketService.getTicketQtyCnt(channelVO.getChannelId());
	    	channelVO.setOffLineQtyCnt(ticketQtyCnt);

	    	TicketCntVO ticketCnt = userTicketOrderService.getTicketSaleCnt(channelVO.getChannelId());
			channelVO.setOffLineSaleCnt(null != ticketCnt?ticketCnt.getOffLineSaleCnt():0);
			channelVO.setOnLineSaleCnt(null != ticketCnt?ticketCnt.getOnLineSaleCnt():0);
	    }

		return AjaxResult.success(channelVO);
	}

}
