package com.jsowell.pile.service.impl;

import cn.hutool.core.util.PageUtil;
import com.google.common.collect.Lists;
import com.jsowell.common.constant.CacheConstants;
import com.jsowell.common.constant.Constants;
import com.jsowell.common.core.domain.entity.SysDept;
import com.jsowell.common.core.domain.vo.AuthorizedDeptVO;
import com.jsowell.common.core.page.PageResponse;
import com.jsowell.common.core.redis.RedisCache;
import com.jsowell.common.util.DateUtils;
import com.jsowell.common.util.DistanceUtils;
import com.jsowell.common.util.SecurityUtils;
import com.jsowell.common.util.StringUtils;
import com.jsowell.common.util.ip.AddressUtils;
import com.jsowell.pile.domain.PileStationInfo;
import com.jsowell.pile.dto.FastCreateStationDTO;
import com.jsowell.pile.dto.QueryStationDTO;
import com.jsowell.pile.mapper.PileStationInfoMapper;
import com.jsowell.pile.service.IPileBasicInfoService;
import com.jsowell.pile.service.IPileBillingTemplateService;
import com.jsowell.pile.service.IPileConnectorInfoService;
import com.jsowell.pile.service.IPileMerchantInfoService;
import com.jsowell.pile.service.IPileStationInfoService;
import com.jsowell.pile.vo.base.ConnectorInfoVO;
import com.jsowell.pile.vo.base.MerchantInfoVO;
import com.jsowell.pile.vo.base.PileInfoVO;
import com.jsowell.pile.vo.base.StationInfoVO;
import com.jsowell.pile.vo.uniapp.CurrentTimePriceDetails;
import com.jsowell.pile.vo.web.PileStationVO;
import com.jsowell.system.service.SysDeptService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 充电站信息Service业务层处理
 *
 * @author jsowell
 * @date 2022-08-30
 */
@Slf4j
@Service
public class PileStationInfoServiceImpl implements IPileStationInfoService {
	@Autowired
	private PileStationInfoMapper pileStationInfoMapper;

	@Autowired
	private IPileConnectorInfoService pileConnectorInfoService;

	@Autowired
	private IPileBillingTemplateService pileBillingTemplateService;

	@Autowired
	private IPileMerchantInfoService pileMerchantInfoService;

	@Autowired
	private SysDeptService sysDeptService;

	@Autowired
	private IPileBasicInfoService pileBasicInfoService;

	@Autowired
	private RedisCache redisCache;



	/**
	 * 查询充电站信息
	 *
	 * @param id 充电站信息主键
	 * @return 充电站信息
	 */
	@Override
	public PileStationInfo selectPileStationInfoById(Long id) {
		// 加缓存
		String redisKey = CacheConstants.SELECT_PILE_STATION_INFO_BY_ID + id;
		PileStationInfo pileStationInfo = redisCache.getCacheObject(redisKey);
		if (pileStationInfo == null) {
			// 查数据库
			pileStationInfo = pileStationInfoMapper.selectPileStationInfoById(id);
			redisCache.setCacheObject(redisKey, pileStationInfo, 15, TimeUnit.MINUTES);
		}
		return pileStationInfo;
	}

	/**
	 * 查询站点基本资料
	 * 加缓存
	 * @param stationId
	 * @return
	 */
	@Override
	public PileStationVO getStationInfo(String stationId) {
		PileStationVO vo = new PileStationVO();
		PileStationInfo pileStationInfo = selectPileStationInfoById(Long.parseLong(stationId));
		// 查计费模板
		CurrentTimePriceDetails currentTimePriceDetails = pileBillingTemplateService.getCurrentTimePriceDetails(stationId);
		if (currentTimePriceDetails != null) {
			vo.setElectricityPrice(new BigDecimal(currentTimePriceDetails.getElectricityPrice()));
			vo.setServicePrice(new BigDecimal(currentTimePriceDetails.getServicePrice()));
		}

		if (pileStationInfo != null) {
			vo.setMerchantId(pileStationInfo.getMerchantId().toString());
			vo.setStationName(pileStationInfo.getStationName());
			vo.setId(pileStationInfo.getId().toString());
			vo.setAreaCode(pileStationInfo.getAreaCode());
			vo.setAddress(pileStationInfo.getAddress());
			if (StringUtils.isNotBlank(pileStationInfo.getQrcodePrefix())) {
				vo.setQrcodePrefix(pileStationInfo.getQrcodePrefix());
			}
			// vo.setMerchantId(pileStationInfo.getMerchantId().toString());
			// vo.setMerchantName(pileStationInfo.getmer());
			vo.setMerchantAdminName(pileStationInfo.getStationAdminName());
			vo.setStationStatus(Integer.parseInt(pileStationInfo.getStationStatus()));
			vo.setStationType(pileStationInfo.getStationType());
			vo.setCreateTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, pileStationInfo.getCreateTime()));
			vo.setStationTel(pileStationInfo.getStationTel());
			vo.setMatchCars(pileStationInfo.getMatchCars());
			if (StringUtils.isNotBlank(pileStationInfo.getMatchCars())) {
				vo.setSelectMatchCars(Lists.newArrayList(pileStationInfo.getMatchCars().split(",")));
			}
			vo.setStationLat(pileStationInfo.getStationLat());
			vo.setStationLng(pileStationInfo.getStationLng());
			vo.setConstruction(pileStationInfo.getConstruction());
			vo.setBusinessHours(pileStationInfo.getBusinessHours());
			// vo.setOrganizationCode(pileStationInfo.getor);
			vo.setPublicFlag(pileStationInfo.getPublicFlag());
			vo.setOpenFlag(pileStationInfo.getOpenFlag());
			vo.setDeptId(pileStationInfo.getDeptId());
			if (StringUtils.isNotBlank(pileStationInfo.getPictures())) {
				vo.setPictures(pileStationInfo.getPictures());
				vo.setPictureList(Lists.newArrayList(pileStationInfo.getPictures().split(",")));
			}
		}
		return vo;
	}

	@Override
	public PileStationVO getStationInfoByPileSn(String pileSn) {
		// 通过pileSn查询充电桩（缓存方法）
		PileInfoVO pileInfoVO = pileBasicInfoService.selectPileInfoBySn(pileSn);
		if (pileInfoVO == null) {
			return null;
		}
		// 通过stationId查询充电站信息（缓存方法）
		PileStationVO stationInfo = getStationInfo(pileInfoVO.getStationId());
		return stationInfo;
	}

	@Override
	public List<PileStationInfo> getStationInfosByThirdParty() {
		// PageUtils.startPage(pageNum, pageSize);
		return pileStationInfoMapper.getStationInfoForLianLian();
	}

	@Override
	public List<String> queryByStationDeptIds(List<String> stationIds) {
		return pileStationInfoMapper.queryByStationDeptIds(stationIds);
	}

	/**
	 * 查询充电站信息列表
	 *
	 * @param pileStationInfo 充电站信息
	 * @return 充电站信息
	 */
	@Override
	public List<PileStationInfo> selectPileStationInfoList(PileStationInfo pileStationInfo) {
		return pileStationInfoMapper.selectPileStationInfoList(pileStationInfo);
	}

	/**
	 * 通过运营商id查询站点信息
	 *
	 * @param merchantId 运营商id
	 * @return 站点信息列表
	 */
    @Override
    public List<PileStationInfo> selectStationListByMerchantId(Long merchantId) {
        return pileStationInfoMapper.selectStationListByMerchantId(merchantId);
    }

    /**
	 * 新增充电站信息
	 *
	 * @param pileStationInfo 充电站信息
	 * @return 结果
	 */
	@Override

	public int insertPileStationInfo(PileStationInfo pileStationInfo) {
		pileStationInfo.setCreateTime(DateUtils.getNowDate());
		pileStationInfo.setCreateBy(SecurityUtils.getUsername());
		return pileStationInfoMapper.insertPileStationInfo(pileStationInfo);
	}

	/**
	 * 快速建站
	 * @param dto
	 * @return
	 */
	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
	public int fastCreateStation(FastCreateStationDTO dto) {
		MerchantInfoVO merchantInfo = pileMerchantInfoService.getMerchantInfo(dto.getMerchantId());
		if (merchantInfo == null) {
			return 0;
		}

		// 1. 新增sys_dept
		SysDept dept = new SysDept();
		// 根据运营商Id查询到对应的部门id
		dept.setParentId(Long.parseLong(merchantInfo.getDeptId()));
		dept.setOrderNum(0);
		dept.setDeptName(dto.getStationName());
		dept.setLeader(dto.getStationAdminName());
		dept.setPhone(dto.getStationTel());
		dept.setStatus("0");
		sysDeptService.insertDept(dept);

		PileStationInfo pileStationInfo = new PileStationInfo();
		// pileStationInfo.setId(dept.getDeptId());
		pileStationInfo.setDeptId(String.valueOf(dept.getDeptId()));
		// 前端输入信息
		pileStationInfo.setMerchantId(Long.valueOf(dto.getMerchantId()));
		pileStationInfo.setStationName(dto.getStationName());
		pileStationInfo.setAddress(dto.getAddress());
		pileStationInfo.setAreaCode(dto.getAreaCode());
		pileStationInfo.setCapacity(BigDecimal.ZERO); // 容量
		pileStationInfo.setStationTel(dto.getStationTel());
		pileStationInfo.setStationAdminName(dto.getStationAdminName());
		// 获取经纬度
		Map<String, String> longitudeAndLatitude = AddressUtils.getLongitudeAndLatitude(dto.getAreaCode(), dto.getAddress());
		if (longitudeAndLatitude != null) {
			pileStationInfo.setStationLng(longitudeAndLatitude.get("lng"));
			pileStationInfo.setStationLat(longitudeAndLatitude.get("lat"));
		}
		pileStationInfo.setCreateBy(SecurityUtils.getUsername());
		int i = pileStationInfoMapper.insertPileStationInfo(pileStationInfo);
		return i;
	}

	/**
	 * 修改充电站信息
	 *
	 * @param pileStationInfo 充电站信息
	 * @return 结果
	 */
	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
	public int updatePileStationInfo(PileStationInfo pileStationInfo) {
		// 清缓存
		String redisKey = CacheConstants.SELECT_PILE_STATION_INFO_BY_ID + pileStationInfo.getId();
		redisCache.deleteObject(redisKey);

		pileStationInfo.setUpdateBy(SecurityUtils.getUsername());
		pileStationInfo.setUpdateTime(DateUtils.getNowDate());
		int i = pileStationInfoMapper.updatePileStationInfo(pileStationInfo);

		// 同步组织中的名称，联系人，电话
		SysDept sysDept = sysDeptService.selectDeptById(Long.parseLong(pileStationInfo.getDeptId()));
		if (sysDept != null) {
			sysDept.setDeptName(pileStationInfo.getStationName());
			sysDept.setLeader(pileStationInfo.getStationAdminName());
			sysDept.setPhone(pileStationInfo.getStationTel());
			sysDept.setUpdateTime(DateUtils.getNowDate());
			sysDeptService.updateDept(sysDept);
		}

		// 再次清缓存
		redisCache.deleteObject(redisKey);
		return i;
	}

	/**
	 * 批量删除充电站信息
	 *
	 * @param ids 需要删除的充电站信息主键
	 * @return 结果
	 */
	@Override
	public int deletePileStationInfoByIds(Long[] ids) {
		return pileStationInfoMapper.deletePileStationInfoByIds(ids);
	}

	/**
	 * 充电站列表信息
	 * @param dto 前台参数
	 * @return 充电站对象集合
	 */
	@Override
	// @DataScope(deptAlias = "t3")
	public List<PileStationVO> queryStationInfos(QueryStationDTO dto) {
		AuthorizedDeptVO authorizedMap = SecurityUtils.getAuthorizedMap();
		if (authorizedMap == null) {
			// 为空表示没有权限，返回空数组
			return Lists.newArrayList();
		}
		dto.setStationDeptIds(authorizedMap.getStationDeptIds());
		dto.setMerchantDeptIds(authorizedMap.getMerchantDeptIds());
		List<PileStationVO> list = pileStationInfoMapper.queryStationInfos(dto);
		return list;
	}

	/**
	 * uniApp查询充电站信息并通过经纬度排序
	 *
	 * @param dto 前台参数
	 * @return 充电站对象集合
	 */
	@Override
	public PageResponse uniAppQueryStationInfoList(QueryStationDTO dto) {
		long pageNum = dto.getPageNum() == 0 ? 1L : dto.getPageNum();
		long pageSize = dto.getPageSize() == 0 ? 10L : dto.getPageSize();

		// 小程序站点列表页只展示对外开放的站点
		dto.setPublicFlag(Constants.ONE);
		// 根据前台参数分页
		List<PileStationVO> list = pileStationInfoMapper.queryStationInfos(dto);

		List<StationInfoVO> stationVOList = Lists.newArrayList();
		StationInfoVO stationVO = null;
		String stationLng = dto.getStationLng();
		String stationLat = dto.getStationLat();
		double distance = 0d;
		for (PileStationVO pileStationVO : list) {
			stationVO = new StationInfoVO();
			if (StringUtils.isNotEmpty(stationLng) && StringUtils.isNotEmpty(stationLat)) {
				try{
					// 计算当前经纬度和站点之间的距离
					distance = DistanceUtils.getDistance(Double.parseDouble(stationLng), Double.parseDouble(stationLat),
							Double.parseDouble(pileStationVO.getStationLng()), Double.parseDouble(pileStationVO.getStationLat()));
					// 保留两位小数
					stationVO.setDistance(String.format("%.2f", distance));
				}catch (Exception e){
					stationVO.setDistance("0.00");
				}

			}
			stationVO.setStationId(pileStationVO.getId());
			stationVO.setStationName(pileStationVO.getStationName());
			stationVO.setStationAddress(pileStationVO.getAddress());
			stationVO.setStationLat(pileStationVO.getStationLat());
			stationVO.setStationLng(pileStationVO.getStationLng());

			// 站点图片
			if (StringUtils.isNotBlank(pileStationVO.getPictures())) {
				stationVO.setStationImgList(Lists.newArrayList(pileStationVO.getPictures().split(",")));
			}

			Map<String, Integer> map = pileConnectorInfoService.getPileTypeNum(Long.parseLong(pileStationVO.getId()));

			Integer fastFree = map.get("fastFree");
			Integer slowFree = map.get("slowFree");

			stationVO.setFastTotal(map.get("fastTotal"));
			stationVO.setFastFree(fastFree);
			stationVO.setSlowTotal(map.get("slowTotal"));
			stationVO.setSlowFree(map.get("slowFree"));
			stationVO.setTotalFree(fastFree + slowFree);

			// 查询当前时段电费
			CurrentTimePriceDetails currentTimePriceDetails = pileBillingTemplateService.getCurrentTimePriceDetails(stationVO.getStationId());
			if (currentTimePriceDetails != null) {
				stationVO.setElectricityPrice(currentTimePriceDetails.getElectricityPrice());
				stationVO.setServicePrice(currentTimePriceDetails.getServicePrice());
				stationVO.setTotalPrice(currentTimePriceDetails.getTotalPrice());
			}
			stationVOList.add(stationVO);
		}

		if (distance != 0.00) {
			// 对集合按照距离排序，距离小的在前
			stationVOList.sort((o1, o2) -> {
				Double a = Double.valueOf(o1.getDistance());
				Double b = Double.valueOf(o2.getDistance());
				return a.compareTo(b);
			});
		}
		List<StationInfoVO> collect = stationVOList.stream()
				.skip((pageNum - 1) * pageSize)
				.limit(pageSize)
				.collect(Collectors.toList());

		int total = stationVOList.size();
		int pages = PageUtil.totalPage(total, dto.getPageSize());
		// 返回结果集
		return PageResponse.builder()
				.pageNum(Integer.parseInt(String.valueOf(pageNum)))
				.pageSize(Integer.parseInt(String.valueOf(pageSize)))
				.list(collect)
				.pages(pages)
				.total(total)
				.build();
	}

	/**
	 * 根据站点id查询运营商配置的汇付会员id
	 * @param stationId
	 * @return
	 */
	@Override
	public String selectAdapayMemberId(String stationId) {
		return null;
	}

}

