package com.yeejoin.amos.maintenance.business.service.impl;

import com.google.common.base.Joiner;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.maintenance.business.constants.XJConstant;
import com.yeejoin.amos.maintenance.business.dao.mapper.PlanMapper;
import com.yeejoin.amos.maintenance.business.dao.repository.IPlanDao;
import com.yeejoin.amos.maintenance.business.dao.repository.IPlanTaskDao;
import com.yeejoin.amos.maintenance.business.dao.repository.IPlanTaskDetailDao;
import com.yeejoin.amos.maintenance.business.dao.repository.IRouteDao;
import com.yeejoin.amos.maintenance.business.param.PlanInfoPageParam;
import com.yeejoin.amos.maintenance.business.service.intfc.IPlanService;
import com.yeejoin.amos.maintenance.core.util.DateUtil;
import com.yeejoin.amos.maintenance.core.util.StringUtil;
import com.yeejoin.amos.maintenance.dao.entity.Plan;
import com.yeejoin.amos.maintenance.dao.entity.Route;
import com.yeejoin.amos.maintenance.feign.RemoteSecurityService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service("planService")
public class PlanServiceImpl implements IPlanService {
    @Autowired
    private IPlanDao planDao;
    @Autowired
    private PlanMapper planMapper;

    @Autowired
    private IPlanTaskDao planTaskDao;

    @Autowired
    private IPlanTaskDetailDao planTaskDetailDao;

    @Autowired
    RemoteSecurityService remoteSecurityService;

    @Autowired
    IRouteDao iRouteDao;

    private static final Logger logger = LoggerFactory.getLogger(PlanServiceImpl.class);

    @Override
    public Page<HashMap<String, Object>> getPlanInfo(PlanInfoPageParam param) {
        long total = planMapper.countPlanInfoData(param);
        Set<String> userIds = new HashSet<>();
        List<HashMap<String, Object>> content = planMapper.getPlanInfo(param);
        content.forEach(c -> userIds.add(c.get("createBy") != null ? c.get("createBy").toString() : ""));
        userIds.remove("");
        String[] temp = Joiner.on(",").join(userIds).split(",");
        Set<String> distinctUserIds = new HashSet<>(Arrays.asList(temp));
        List<AgencyUserModel> userModels = remoteSecurityService.listUserByUserIds(Joiner.on(",").join(distinctUserIds));
        Map<String, String> userIdNameMap = userModels.stream().collect(Collectors.toMap(AgencyUserModel::getUserId, AgencyUserModel::getRealName));
        content.forEach(c -> {
            this.buildUserName(c, "createBy", userIdNameMap);
        });
        return new PageImpl<>(content, param, total);
    }

    private void buildUserNames(HashMap<String, Object> c, String key, Map<String, String> userIdNameMap) {
        String[] userIdArray = c.get(key) != null ? c.get(key).toString().split(",") : new String[1];
        Set<String> names = new HashSet<>();
        for (String userId : userIdArray) {
            names.add(userIdNameMap.get(userId));
        }
        names.remove(null);
        names.remove("");
        c.put(key + "Name", String.join(",", names));
    }

    private void buildUserName(HashMap<String, Object> c, String key, Map<String, String> userIdNameMap) {
        String userId = c.get(key) != null ? c.get(key).toString() : "";
        c.put(key + "Name", userIdNameMap.get(userId));
    }

    @Override
    public void addPlan(HashMap<String, Object> map) {
        Plan param = (Plan) map.get("param");
        String orgCode = map.get("org_code") == null ? "" : map.get("org_code").toString();
        String userId = map.get("user_id") == null ? "" : map.get("user_id").toString();
        param.setOrgCode(orgCode);
        param.setStatus(Byte.parseByte(XJConstant.PLAN_STATUS_START));
        param.setNextGenDate(DateUtil.getIntervalDate(new Date(), 0));
        param.setCreateBy(userId);
        //编辑计划
        if (param.getId() > 0) {
            Plan oriPlan = planDao.findById(param.getId()).get();
            param.setCreateDate(oriPlan.getCreateDate());
            param.setCreateBy(oriPlan.getCreateBy());
            param.setLastUpdBy(userId);
            param.setFirstFlag(XJConstant.PLAN_FIRST_STATUS_YES);
        }
        if (XJConstant.FIX_DATE_NO.equals(param.getIsFixedDate()) && (XJConstant.PLAN_TYPE_MONTH.equals(param.getPlanType()) || XJConstant.PLAN_TYPE_YEAR.equals(param.getPlanType()))) {
            param.setDayBegin(DateUtil.formatStrToTime("00:00:00"));
            param.setDayEnd(DateUtil.formatStrToTime("23:59:59"));
        }
        planDao.save(param);
    }

    @Override
    @Transactional
    public void delPlanById(String[] param) {
        List<Long> ids = new ArrayList<Long>();
        for (int i = 0; i < param.length; i++) {
            ids.add(Long.parseLong(param[i]));
        }
        planDao.updatePlanDel(ids);
        // 删除对应该计划今天往后的所有计划执行信息
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Date zero = calendar.getTime();
        List<Long> taskIdList = planTaskDao.getPlanTaskIdByPlanIdAndDate(ids, zero);
        if (taskIdList.size() > 0) {
            planTaskDao.deletePlanTaskByIdAndDate(ids, zero);

            // 删除对应该计划的计划执行详情新
            planTaskDetailDao.deletePlanTaskDetailByTaskNo(taskIdList);
        }

    }

    @Override
    public void planSaveAs(String[] param) {
        for (int i = 0; i < param.length; i++) {
            planMapper.saveAs(param[i]);
        }

    }

    @Override
    public List<Plan> getPlanByRouteId(Long routeId) {
        List<Plan> planList = planMapper.getPlanByRouteId(routeId);
        return planList;
    }

    @Override
    public void disablePlan(Long[] planIds) {
        // plan表中status字段置为1
        for (long planId : planIds) {
            List<Plan> planList = getPlanByRouteId(planId);
            for (Plan plan : planList) {
                plan.setStatus((byte) 1);
                planDao.save(plan);
            }
        }
    }

    @Override
    public Plan queryPlanById(Long id) {
        Plan plan = null;
        Optional<Plan> op = planDao.findById(id);
        if(op.isPresent()){
            plan = op.get();
            Optional<Route> optionalRoute = iRouteDao.findById(plan.getRouteId());
            plan.setOwnerId( optionalRoute.isPresent() ? optionalRoute.get().getOwnerId() : "" );
        }
        return plan;
    }

    @Override
    public List<HashMap<String, Object>> getPlanInfoNoPage(PlanInfoPageParam param) {
        return planMapper.getPlanInfoNoPage(param);
    }

    @Override
    public List<HashMap<String, Object>> queryPlanListByOrgCode(String loginOrgCode) {
        return planMapper.queryPlanListByOrgCode(loginOrgCode);
    }


}
