package com.jsowell.pile.service.impl;

import com.google.common.collect.Lists;
import com.jsowell.common.constant.Constants;
import com.jsowell.common.core.domain.entity.SysDept;
import com.jsowell.common.core.domain.entity.SysUser;
import com.jsowell.common.core.domain.vo.AuthorizedDeptVO;
import com.jsowell.common.enums.adapay.AdapayPayChannelEnum;
import com.jsowell.common.enums.ykc.ReturnCodeEnum;
import com.jsowell.common.exception.BusinessException;
import com.jsowell.common.util.DateUtils;
import com.jsowell.common.util.DictUtils;
import com.jsowell.common.util.PageUtils;
import com.jsowell.common.util.StringUtils;
import com.jsowell.pile.domain.PileMerchantInfo;
import com.jsowell.pile.dto.CreateMerchantDTO;
import com.jsowell.pile.dto.QueryMerchantInfoDTO;
import com.jsowell.pile.mapper.PileMerchantInfoMapper;
import com.jsowell.pile.service.PileMerchantInfoService;
import com.jsowell.pile.util.UserUtils;
import com.jsowell.pile.vo.base.MerchantInfoVO;
import com.jsowell.pile.vo.web.MerchantSettleInfoVO;
import com.jsowell.pile.vo.web.PileMerchantInfoVO;
import com.jsowell.system.service.SysDeptService;
import com.jsowell.system.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * 充电桩运营商信息Service业务层处理
 *
 * @author jsowell
 * @date 2022-08-27
 */
@Slf4j
@Service
public class PileMerchantInfoServiceImpl implements PileMerchantInfoService {
	@Autowired
	private PileMerchantInfoMapper pileMerchantInfoMapper;

	@Autowired
	private SysDeptService sysDeptService;

	@Autowired
	private SysUserService userService;

	/**
	 * 查询充电桩运营商信息
	 *
	 * @param id 充电桩运营商信息主键
	 * @return 充电桩运营商信息
	 */
	@Override
	public PileMerchantInfo selectPileMerchantInfoById(Long id) {
		return pileMerchantInfoMapper.selectPileMerchantInfoById(id);
	}

	@Override
	public PileMerchantInfo selectPileMerchantInfoById(String merchantId) {
		return selectPileMerchantInfoById(Long.parseLong(merchantId));
	}

	/**
	 * 查询充电桩运营商信息列表
	 * 带权限校验
	 * @param pileMerchantInfo 充电桩运营商信息
	 * @return 充电桩运营商信息
	 */
	@Override
	public List<PileMerchantInfo> selectPileMerchantInfoListWithAuth(PileMerchantInfo pileMerchantInfo) {
		// 当前登录用户的运营商权限列表
		List<MerchantInfoVO> list = UserUtils.getMerchantInfoVOList();
		if (CollectionUtils.isNotEmpty(list)) {
			List<String> collect = list.stream().map(MerchantInfoVO::getDeptId).collect(Collectors.toList());
			pileMerchantInfo.setMerchantDeptIds(collect);
		}
		return selectPileMerchantInfoList(pileMerchantInfo);
	}

	/**
	 * 分页查询充电桩运营商信息列表
	 * 带权限校验
	 * @param pileMerchantInfo 充电桩运营商信息
	 * @return 充电桩运营商信息
	 */
	@Override
	public List<PileMerchantInfo> pagePileMerchantInfoListWithAuth(PileMerchantInfo pileMerchantInfo) {
		// 当前登录用户的运营商权限列表
		List<MerchantInfoVO> list = UserUtils.getMerchantInfoVOList();
		if (CollectionUtils.isNotEmpty(list)) {
			List<String> collect = list.stream().map(MerchantInfoVO::getDeptId).collect(Collectors.toList());
			pileMerchantInfo.setMerchantDeptIds(collect);
		}
		PageUtils.startPage();
		return selectPileMerchantInfoList(pileMerchantInfo);
	}

	/**
	 * 查询充电桩运营商信息列表
	 * 无权限校验
	 * @param pileMerchantInfo 充电桩运营商信息
	 * @return 充电桩运营商信息
	 */
	@Override
	public List<PileMerchantInfo> selectPileMerchantInfoList(PileMerchantInfo pileMerchantInfo) {
		List<PileMerchantInfo> list = pileMerchantInfoMapper.selectPileMerchantInfoList(pileMerchantInfo);
		if (Objects.nonNull(list)) {
			for (PileMerchantInfo p:list) {
				String status = p.getStatus();
				String merchant_status = DictUtils.getDictLabel("merchant_status", status);
				p.setStatus(merchant_status);
			}
		}
		return list;
	}

	@Override
	public List<PileMerchantInfo> selectPileMerchantInfoListByIdList(List<String> merchantIdList) {
		return pileMerchantInfoMapper.selectPileMerchantInfoListByIdList(merchantIdList);
	}

	/**
	 * 新增充电桩运营商信息
	 *
	 * @param dto 充电桩运营商信息
	 * @return 结果
	 */
	@Override
	@Transactional
	public int insertPileMerchantInfo(CreateMerchantDTO dto) {
		// 校验参数
		verifyParameters(dto);

		// 1. 新增sys_dept
		SysDept dept = new SysDept();
		dept.setParentId(100L);
		dept.setOrderNum(0);
		dept.setDeptName(dto.getMerchantName());
		dept.setLeader(dto.getManagerName());
		dept.setPhone(dto.getManagerPhone());
		dept.setDeptLevel("2");
		dept.setStatus("0");
		sysDeptService.insertDept(dept);

		// 2. 新增pile_merchant_info
		Long deptId = dept.getDeptId();
		// dto.setId(deptId);
		dto.setDeptId(String.valueOf(deptId));
		dto.setStatus(Constants.ONE);

		// 一级运营商取前端传来的appid，二级运营商取父级的appid
		String appId;
		if (StringUtils.equals(dto.getMerchantLevel(), Constants.TWO)) {
			PileMerchantInfo firstLevelMerchant = selectPileMerchantInfoById(Long.parseLong(dto.getParentId()));
			appId = firstLevelMerchant.getAppId();
		} else {
			appId = dto.getAppId();
		}
		dto.setAppId(appId);

		PileMerchantInfo pileMerchantInfo = new PileMerchantInfo();
		BeanUtils.copyProperties(dto, pileMerchantInfo);
		int i = pileMerchantInfoMapper.insertPileMerchantInfo(pileMerchantInfo);

		// 3 创建运营商管理员
		if (StringUtils.isNotBlank(dto.getManagerPhone())) {
			SysUser user = new SysUser();
			user.setDeptId(deptId);
			user.setUserName(dto.getManagerPhone());
			user.setNickName(dto.getMerchantName() + "-管理员");
			user.setPassword("a" + dto.getManagerPhone());
			user.setStatus(Constants.ZERO);
			user.setPostIds(new Long[]{});
			user.setRoleIds(new Long[]{3L});
			userService.createUser(user);
		}
		return i;
	}

	/**
	 * verifyParameters
	 */
	private void verifyParameters(CreateMerchantDTO dto) {
		PileMerchantInfo pileMerchantInfo;
		// 校验组织机构代码是否重复
		if (StringUtils.isNotBlank(dto.getOrganizationCode())) {
			pileMerchantInfo = new PileMerchantInfo();
			pileMerchantInfo.setOrganizationCode(dto.getOrganizationCode());
			List<PileMerchantInfo> pileMerchantInfos = pileMerchantInfoMapper.selectPileMerchantInfoList(pileMerchantInfo);
			if (CollectionUtils.isNotEmpty(pileMerchantInfos)) {
				throw new BusinessException("", "输入的组织机构代码已存在");
			}
		}

		// 校验运营商名称是否重复
		if (StringUtils.isNotBlank(dto.getMerchantName())) {
			pileMerchantInfo = new PileMerchantInfo();
			pileMerchantInfo.setMerchantName(dto.getMerchantName());
			List<PileMerchantInfo> pileMerchantInfos = pileMerchantInfoMapper.selectPileMerchantInfoList(pileMerchantInfo);
			if (CollectionUtils.isNotEmpty(pileMerchantInfos)) {
				for (PileMerchantInfo merchantInfo : pileMerchantInfos) {
					if (StringUtils.equals(merchantInfo.getMerchantName(), dto.getMerchantName())) {
						throw new BusinessException("", "输入的运营商名称已存在");
					}
				}
			}
		}

		// 校验手机号是否重复
		if (StringUtils.isNotBlank(dto.getManagerPhone())) {
			pileMerchantInfo = new PileMerchantInfo();
			pileMerchantInfo.setManagerPhone(dto.getManagerPhone());
			List<PileMerchantInfo> pileMerchantInfos = pileMerchantInfoMapper.selectPileMerchantInfoList(pileMerchantInfo);
			if (CollectionUtils.isNotEmpty(pileMerchantInfos)) {
				throw new BusinessException("", "输入的管理员电话已存在");
			}
		}
	}

	/**
	 * 修改充电桩运营商信息
	 *
	 * @param pileMerchantInfo 充电桩运营商信息
	 * @return 结果
	 */
	@Override
	public int updatePileMerchantInfo(PileMerchantInfo pileMerchantInfo) {
		pileMerchantInfo.setUpdateTime(DateUtils.getNowDate());
		// 如果修改运营商名称，需将 sys_menu 表中的 dept_name 字段对应修改
		String deptId = pileMerchantInfo.getDeptId();
		SysDept sysDept = sysDeptService.selectDeptById(Long.parseLong(deptId));
		if (sysDept == null) {
			return 0;
		}
		if (!StringUtils.equals(pileMerchantInfo.getMerchantName(), sysDept.getDeptName())) {
			// 不一致，进行修改
			sysDept.setDeptName(pileMerchantInfo.getMerchantName());
			sysDeptService.updateDept(sysDept);
		}
		return pileMerchantInfoMapper.updatePileMerchantInfo(pileMerchantInfo);
	}

	/**
	 * 批量删除充电桩运营商信息
	 *
	 * @param ids 需要删除的充电桩运营商信息主键
	 * @return 结果
	 */
	@Override
	public int deletePileMerchantInfoByIds(Long[] ids) {
		int i = pileMerchantInfoMapper.deletePileMerchantInfoByIds(ids);
		deleteMerchantDept(Lists.newArrayList(ids));
		return i;
	}

	/**
	 * 删除充电桩运营商信息信息
	 *
	 * @param id 充电桩运营商信息主键
	 * @return 结果
	 */
	@Override
	public int deletePileMerchantInfoById(Long id) {
		int i = pileMerchantInfoMapper.deletePileMerchantInfoById(id);
		// 删除对应部门
		deleteMerchantDept(Lists.newArrayList(id));
		return i;
	}

	private void deleteMerchantDept(List<Long> merchantIds) {
		if (CollectionUtils.isEmpty(merchantIds)) {
			return;
		}
		for (Long merchantId : merchantIds) {
			// 查询出来运营商信息
			PileMerchantInfo pileMerchantInfo = selectPileMerchantInfoById(merchantId);
			if (pileMerchantInfo == null) {
				continue;
			}
			// 部门id
			String deptId = pileMerchantInfo.getDeptId();

			// 逻辑删除部门的用户
			SysUser user = new SysUser();
			user.setDeptId(Long.parseLong(deptId));
			List<SysUser> userList = userService.selectUserList(user);
			if (CollectionUtils.isNotEmpty(userList)) {
				Long[] array = userList.stream().map(SysUser::getUserId).toArray(Long[]::new);
				userService.deleteUserByIds(array);
			}

			// 逻辑删除部门
			sysDeptService.deleteDeptById(Long.parseLong(deptId));
		}
	}

	/**
	 * 通过微信小程序appId查询一级运营商merchant对象
	 * @param wxAppId 微信小程序appId
	 * @return 一级运营商merchant对象
	 */
	@Override
	public PileMerchantInfo getFirstLevelMerchantByWxAppId(String wxAppId) {
		if (StringUtils.isBlank(wxAppId)) {
			return null;
		}
		return pileMerchantInfoMapper.getFirstLevelMerchantByWxAppId(wxAppId);
	}

	/**
	 * 通过支付宝小程序appId查询一级运营商merchant对象
	 * @param alipayAppId 支付宝小程序appId
	 * @return 一级运营商merchant对象
	 */
	@Override
	public PileMerchantInfo getFirstLevelMerchantByAlipayAppId(String alipayAppId) {
		if (StringUtils.isBlank(alipayAppId)) {
			return null;
		}
		return pileMerchantInfoMapper.getFirstLevelMerchantByAlipayAppId(alipayAppId);
	}

	/**
	 * 通过微信小程序appId查询一级运营商merchantId
	 * @param wechatAppId 微信小程序appId
	 * @return 一级运营商merchantId
	 */
	@Override
	public String getFirstLevelMerchantIdByWxAppId(String wechatAppId) {
		String merchantId = null;
		PileMerchantInfo merchant = getFirstLevelMerchantByWxAppId(wechatAppId);
		if (Objects.nonNull(merchant)) {
			merchantId = String.valueOf(merchant.getId());
		}
		return merchantId;
	}

	/**
	 * 通过支付宝小程序appId查询一级运营商merchantId
	 * @param alipayAppId 支付宝小程序appId
	 * @return 一级运营商merchantId
	 */
	@Override
	public String getFirstLevelMerchantIdByAliAppId(String alipayAppId) {
		String merchantId = null;
		PileMerchantInfo merchant = getFirstLevelMerchantByAlipayAppId(alipayAppId);
		if (Objects.nonNull(merchant)) {
			merchantId = String.valueOf(merchant.getId());
		}
		return merchantId;
	}



	@Override
	public MerchantInfoVO getMerchantInfoVO(String merchantId) {
		PileMerchantInfo pileMerchantInfo = selectPileMerchantInfoById(Long.parseLong(merchantId));
		if (pileMerchantInfo == null) {
			return null;
		}
		return conversion2MerchantInfoVO(pileMerchantInfo);
	}

	/**
	 * PileMerchantInfo 转换为 MerchantInfoVO
	 * @param pileMerchantInfo
	 * @return
	 */
	private MerchantInfoVO conversion2MerchantInfoVO(PileMerchantInfo pileMerchantInfo) {
		MerchantInfoVO vo = MerchantInfoVO.builder()
				.merchantId(String.valueOf(pileMerchantInfo.getId()))
				.merchantName(pileMerchantInfo.getMerchantName())
				.merchantTel(pileMerchantInfo.getServicePhone())
				.organizationCode(pileMerchantInfo.getOrganizationCode())
				.deptId(pileMerchantInfo.getDeptId())
				.merchantLevel(pileMerchantInfo.getMerchantLevel())
				.build();
		return vo;
	}

	@Override
	public List<String> queryByMerchantDeptIds(List<String> merchantDeptIds) {
		return pileMerchantInfoMapper.queryByMerchantDeptIds(merchantDeptIds);
	}

	@Override
	public PileMerchantInfo queryInfoByDeptId(String deptId) {
		if (StringUtils.isBlank(deptId)) {
			return null;
		}
		return pileMerchantInfoMapper.queryInfoByDeptId(deptId);
	}

	@Override
	public MerchantInfoVO queryMerchantInfoVOByDeptId(String deptId) {
		PileMerchantInfo merchantInfo = queryInfoByDeptId(deptId);
		if (Objects.isNull(merchantInfo)) {
			return null;
		}
		return conversion2MerchantInfoVO(merchantInfo);
	}

	/**
	 * 通过ids查询信息列表
	 * @param dto
	 * @return
	 */
	@Override
	public List<MerchantSettleInfoVO> queryMerchantInfoListByAuth(QueryMerchantInfoDTO dto) {
		if (CollectionUtils.isEmpty(dto.getDeptIds())) {
			dto.setDeptIds(Lists.newArrayList());
		}
		// 权限过滤
		AuthorizedDeptVO authorizedMap = UserUtils.getAuthorizedMap();
		if (authorizedMap == null) {
			// 为空表示没有权限，返回空数组
			return new ArrayList<>();
		}
		String parentId = authorizedMap.getParentId();
		// 父级id为0代表 thinkgem/jskf 账号
		if (!StringUtils.equals("0", parentId)) {
			String deptId = authorizedMap.getDeptId();
			dto.getDeptIds().add(deptId);
		}
		// return pileMerchantInfoMapper.queryInfoListByIds(deptIds);
		return pileMerchantInfoMapper.queryMerchantSettleInfoList(dto);
	}


	/**
	 * 查询一级运营商列表
	 * @return
	 */
	@Override
	public List<PileMerchantInfo> queryFirstLevelMerchantList() {
		return pileMerchantInfoMapper.queryFirstLevelMerchantList();
	}

	/**
	 * 通过merchantId查询appId
	 */
	@Override
	public String queryAppIdByMerchantId(String merchantId) {
		if (StringUtils.isBlank(merchantId)) {
			return null;
		}
		/*
		 一般情况下新建的运营商appId都是有值的，某些早前建的运营商appId可能为空
		 一级运营商就是自己的appId, 二级运营商使用一级运营商的appId
		 */
		PileMerchantInfo pileMerchantInfo = selectPileMerchantInfoById(Long.parseLong(merchantId));
		if (pileMerchantInfo == null) {
			return null;
		}
		String appId = pileMerchantInfo.getAppId();
		if (StringUtils.isNotBlank(appId)) {
			return appId;
		}
		// 如果appId为空，则查询父级（一级运营商的appId）
		PileMerchantInfo parent = selectPileMerchantInfoById(Long.parseLong(pileMerchantInfo.getParentId()));
		if (parent == null) {
			return null;
		}
		appId = parent.getAppId();
		if (StringUtils.isNotBlank(appId)) {
			// 异步方法 把appId更新到二级运营商
			String finalAppId = appId;
			CompletableFuture.runAsync(() -> {
				PileMerchantInfo update = new PileMerchantInfo();
				update.setId(Long.parseLong(merchantId));
				update.setAppId(finalAppId);
				updatePileMerchantInfo(update);
			});
			return appId;
		}
		return appId;
	}

	/**
	 * 通过appid查询运营商部门id
	 * @param appId
	 * @return
	 */
    @Override
    public List<String> getDeptIdsByAppId(String appId) {
        return pileMerchantInfoMapper.getDeptIdsByWxAppId(appId);
    }

	/**
	 * 通过wechatAppId查询一级运营商的延时支付模式配置
	 * @param wechatAppId 微信小程序id
	 * @return
	 */
	// @Override
	// public String getDelayModeByWechatAppId(String wechatAppId) {
	// 	PileMerchantInfo merchant = getFirstLevelMerchantByAppId(wechatAppId);
	// 	if (merchant != null) {
	// 		String delayMode = merchant.getDelayMode();
	// 		if (StringUtils.equals(delayMode, Constants.ONE)) {
	// 			return Constants.ADAPAY_PAY_MODE_DELAY;
	// 		}
	// 	}
	// 	return null;
	// }

	@Override
	public String getDelayModeByAppIdAndRequestSource(String appId, String requestSource) {
		String delayMode = "";
		if (StringUtils.equals(requestSource, AdapayPayChannelEnum.WX_LITE.getValue())) {
			delayMode = getDelayModeByWechatAppId(appId);
		} else if (StringUtils.equals(requestSource, AdapayPayChannelEnum.ALIPAY_LITE.getValue())) {
			delayMode = getDelayModeByAlipayAppId(appId);
		} else {
			throw new BusinessException("", "未知来源");
		}
		return delayMode;
	}

	/**
	 * 通过wechatAppId查询一级运营商的延时支付模式配置
	 * @param wechatAppId 微信小程序id
	 * @return 延时分账模式（0-不延时；1-延时分账）
	 */
	@Override
	public String getDelayModeByWechatAppId(String wechatAppId) {
		PileMerchantInfo merchant = getFirstLevelMerchantByWxAppId(wechatAppId);
		if (merchant == null) {
			throw new BusinessException(ReturnCodeEnum.CODE_GET_FIRST_LEVEL_MERCHANT_BY_APP_ID);
		}
		return merchant.getDelayMode();
	}

	/**
	 * 通过wechatAppId查询一级运营商的延时支付模式配置
	 * @param alipayAppId 微信小程序id
	 * @return 延时分账模式（0-不延时；1-延时分账）
	 */
	@Override
	public String getDelayModeByAlipayAppId(String alipayAppId) {
		PileMerchantInfo merchant = getFirstLevelMerchantByAlipayAppId(alipayAppId);
		if (merchant == null) {
			throw new BusinessException(ReturnCodeEnum.CODE_GET_FIRST_LEVEL_MERCHANT_BY_APP_ID);
		}
		return merchant.getDelayMode();
	}

	/**
	 * 通过运营商id查询一级运营商配置的delayMode
	 * @param merchantId
	 * @return
	 */
	@Override
	public String getDelayModeByMerchantId(String merchantId) {
		PileMerchantInfo merchant = getFirstLevelMerchantByMerchantId(merchantId);
		if (merchant == null) {
			return null;
		}
		return merchant.getDelayMode();
	}

	@Override
	public PileMerchantInfo getFirstLevelMerchantByMerchantId(String merchantId) {
		if (StringUtils.isBlank(merchantId)) {
			return null;
		}
		// 拿merchantId先查一次
		PileMerchantInfo pileMerchantInfo = selectPileMerchantInfoById(merchantId);
		if (pileMerchantInfo == null) {
			return null;
		}
		if (StringUtils.equals(pileMerchantInfo.getMerchantLevel(), Constants.ONE)) {
			// 如果是一级运营商直接返回
			return pileMerchantInfo;
		}
		// 通过parentId再查一次
		String parentId = pileMerchantInfo.getParentId();
		pileMerchantInfo = selectPileMerchantInfoById(parentId);
		if (pileMerchantInfo == null) {
			return null;
		}
		return pileMerchantInfo;
	}

    @Override
    public String getFirstLevelMerchantIdByMerchantId(String merchantId) {
		PileMerchantInfo merchantInfo = getFirstLevelMerchantByMerchantId(merchantId);
		if (merchantInfo != null) {
			return String.valueOf(merchantInfo.getId());
		}
		return null;
    }

	/**
	 * 查询全部运营商信息
	 * @return
	 */
	@Override
	public List<MerchantInfoVO> selectAll() {
		List<MerchantInfoVO> resultList = Lists.newArrayList();
		List<PileMerchantInfo> pileMerchantInfos = pileMerchantInfoMapper.selectPileMerchantInfoList(null);
		for (PileMerchantInfo pileMerchantInfo : pileMerchantInfos) {
			resultList.add(conversion2MerchantInfoVO(pileMerchantInfo));
		}
		return resultList;
	}

	@Override
	public List<MerchantInfoVO> selectListByFirstMerchant(String firstMerchantId) {
		List<MerchantInfoVO> resultList = Lists.newArrayList();
		// 查询运营商下属的二级运营商
		List<PileMerchantInfo> pileMerchantInfos = pileMerchantInfoMapper.selectListByFirstMerchant(firstMerchantId);
		if (CollectionUtils.isEmpty(pileMerchantInfos)) {
			return resultList;
		}
		for (PileMerchantInfo pileMerchantInfo : pileMerchantInfos) {
			resultList.add(conversion2MerchantInfoVO(pileMerchantInfo));
		}
		return resultList;
	}

	/**
	 * 通过站点id查询运营商基本信息
	 * @param stationId
	 * @return
	 */
    @Override
    public PileMerchantInfoVO queryMerchantInfoByStationId(String stationId) {
        return pileMerchantInfoMapper.queryMerchantInfoByStationId(stationId);
    }

}
