package com.mortals.xhx.module.window.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.framework.model.OrderCol;
import com.mortals.framework.model.PageInfo;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.xhx.base.system.user.service.UserService;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.common.pdu.RespData;
import com.mortals.xhx.common.pdu.window.WindowPdu;
import com.mortals.xhx.common.pdu.workman.WorkmanPdu;
import com.mortals.xhx.common.utils.BeanUtil;
import com.mortals.xhx.feign.window.IWindowFeign;
import com.mortals.xhx.feign.workman.IWorkmanFeign;
import com.mortals.xhx.module.perform.model.PerformErrorMessageEntity;
import com.mortals.xhx.module.perform.model.PerformErrorMessageQuery;
import com.mortals.xhx.module.perform.model.vo.StaffErrorMessageVo;
import com.mortals.xhx.module.perform.service.PerformErrorMessageService;
import com.mortals.xhx.module.staff.model.StaffEntity;
import com.mortals.xhx.module.staff.model.StaffQuery;
import com.mortals.xhx.module.staff.service.StaffService;
import com.mortals.xhx.module.window.dao.WindowOwnerDao;
import com.mortals.xhx.module.window.model.*;
import com.mortals.xhx.module.window.service.WindowOwnerDetailService;
import com.mortals.xhx.module.window.service.WindowOwnerService;
import com.mortals.xhx.module.window.service.WindowPerformService;
import com.mortals.xhx.module.window.service.WindowWorkmanPerformService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

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

/**
 * WindowOwnerService
 * 窗口负责人 service实现
 *
 * @author zxfei
 * @date 2024-01-26
 */
@Service("windowOwnerService")
@Slf4j
public class WindowOwnerServiceImpl extends AbstractCRUDServiceImpl<WindowOwnerDao, WindowOwnerEntity, Long> implements WindowOwnerService {

    @Autowired
    private WindowOwnerDetailService windowOwnerDetailService;
    @Autowired
    private IWindowFeign windowFeign;
    @Autowired
    private StaffService staffService;
    @Autowired
    private WindowPerformService windowPerformService;
    @Autowired
    private WindowWorkmanPerformService windowWorkmanPerformService;
    @Autowired
    private IWorkmanFeign workmanFeign;
    @Autowired
    private PerformErrorMessageService performErrorMessageService;


    @Override
    public List<WindowPdu> subWindowPduList(WindowPdu pdu) {
        List<WindowPdu> ownerList = new ArrayList<>();
        List<WindowPdu> subList = new ArrayList<>();
        List<WindowPdu> subTwoList = new ArrayList<>();
        List<WindowOwnerDetailEntity> ownerDetail = windowOwnerDetailService.getAllList();
        if (!CollectionUtils.isEmpty(ownerDetail)) {
            Long[] windows = ownerDetail.stream().map(WindowOwnerDetailEntity::getWindowId).toArray(Long[]::new);
            pdu.setIdNotList(Arrays.asList(windows));
            if (pdu.getSiteId() == null) {
                pdu.setSiteId(1l); //默认只查宜宾市民中心
            }
            pdu.setSize(-1);
            Rest<RespData<List<WindowPdu>>> respDataRest = windowFeign.list(pdu);
            log.info(JSONObject.toJSONString(respDataRest));
            if (respDataRest.getCode() == YesNoEnum.YES.getValue()) {
                subList = respDataRest.getData().getData();
            }

           /* if (!ObjectUtils.isEmpty(pdu.getStaffId())) {
                //查询当前负责人负责的窗口
                WindowOwnerDetailQuery detailQuery = new WindowOwnerDetailQuery();
                detailQuery.setOwnerId(pdu.getStaffId());
                Long[] windowIds = windowOwnerDetailService.find(detailQuery).stream().map(WindowOwnerDetailEntity::getWindowId).toArray(Long[]::new);
                if (!ObjectUtils.isEmpty(windowIds)) {
                    WindowPdu ownerWindowPdu = new WindowPdu();
                    ownerWindowPdu.setIdList(Arrays.asList(windowIds));
                    Rest<RespData<List<WindowPdu>>> ownerRest = windowFeign.list(ownerWindowPdu);
                    if (ownerRest.getCode() == YesNoEnum.YES.getValue()) {
                        ownerRest.getData().getData().stream().forEach(item -> {
                            item.setSelected(YesNoEnum.YES.getValue());
                        });
                        subTwoList = ownerRest.getData().getData();
                    }
                }
            }*/
        }else{
            if (pdu.getSiteId() == null) {
                pdu.setSiteId(1l); //默认只查宜宾市民中心
            }
            pdu.setSize(-1);
            Rest<RespData<List<WindowPdu>>> respDataRest = windowFeign.list(pdu);
            log.info(JSONObject.toJSONString(respDataRest));
            if (respDataRest.getCode() == YesNoEnum.YES.getValue()) {
                subList = respDataRest.getData().getData();
            }

        }
        ownerList.addAll(subList);
        ownerList.addAll(subTwoList);
        ownerList = ownerList.parallelStream().sorted(Comparator.comparing(WindowPdu::getSelected).reversed()).collect(Collectors.toList());
        if (!ObjectUtils.isEmpty(pdu.getHallId())) {
            ownerList = ownerList.stream().filter(f -> pdu.getHallId().equals(f.getHallId())).collect(Collectors.toList());
        }


        return ownerList;
    }

    @Override
    public List<WindowOwnerDetailEntity> ownerWindowList(Context context) {
        Long customerId = context.getUser().getCustomerId();
        if (ObjectUtils.isEmpty(customerId)) throw new AppException("系统用户关联客户ID为空！");
        List<WindowOwnerDetailEntity> windowOwnerDetailEntities = windowOwnerDetailService.find(new WindowOwnerDetailQuery().ownerId(customerId));
        return windowOwnerDetailEntities;
    }

    @Override
    public Rest<List<StaffEntity>> getWindowPerson(Long windowId, Context context) {
        WorkmanPdu workmanPdu = new WorkmanPdu();
        workmanPdu.setWindowId(windowId);
        Rest<RespData<List<WorkmanPdu>>> rest = workmanFeign.list(workmanPdu);
        if (rest.getCode() == YesNoEnum.YES.getValue()) {
            List<StaffEntity> staffEntityList = rest.getData().getData().stream().map(item -> {
                //转换成staf
                String name = item.getName();
                String mobile = item.getMobile();
                if (!ObjectUtils.isEmpty(mobile)) {
                    StaffEntity staffEntity = staffService.selectOne(new StaffQuery().phoneNumber(mobile));
                    if (!ObjectUtils.isEmpty(staffEntity)) {
                        return staffEntity;
                    }
                    return getStaffEntityByName(name);
                } else if (!ObjectUtils.isEmpty(name)) {
                    //通过名字查找
                    return getStaffEntityByName(name);
                } else {
                    log.info("未找到对应员工:{}", JSON.toJSONString(item));
                    return null;
                }
            }).collect(Collectors.toList());
            return Rest.ok(staffEntityList);
        }else{

        }
        return Rest.fail("获取窗口工作人员失败");
    }


    private StaffEntity getStaffEntityByName(String name) {
        StaffEntity staffEntity = staffService.selectOne(new StaffQuery().name(name));
        if (!ObjectUtils.isEmpty(staffEntity)) {
            return staffEntity;
        } else {
            return null;
        }
    }

    @Override
    protected void saveBefore(WindowOwnerEntity entity, Context context) throws AppException {
        super.saveBefore(entity, context);
        if (!ObjectUtils.isEmpty(entity.getWindowOwnerDetailList())) {
            entity.setWindowCount(entity.getWindowOwnerDetailList().size());
        }

        WindowOwnerEntity windowOwnerEntity = this.selectOne(new WindowOwnerQuery().staffId(entity.getStaffId()));
        if(!ObjectUtils.isEmpty(windowOwnerEntity)){
            throw new AppException("已经存在该负责人窗口记录！");
        }

        if(CollectionUtils.isNotEmpty(entity.getStaffIdList())){
            entity.setStaffIds(StringUtils.join(entity.getStaffIdList(),","));
        }else {
            entity.setStaffIds("");
        }
    }

    @Override
    protected void updateBefore(WindowOwnerEntity entity, Context context) throws AppException {
        super.updateBefore(entity, context);
        if (!ObjectUtils.isEmpty(entity.getWindowOwnerDetailList())) {
            entity.setWindowCount(entity.getWindowOwnerDetailList().size());
        }
        if(CollectionUtils.isNotEmpty(entity.getStaffIdList())){
            entity.setStaffIds(StringUtils.join(entity.getStaffIdList(),","));
        }else {
            entity.setStaffIds("");
        }
    }

    @Override
    protected void saveAfter(WindowOwnerEntity entity, Context context) throws AppException {
        if (!ObjectUtils.isEmpty(entity.getWindowOwnerDetailList())) {
            entity.getWindowOwnerDetailList().stream().peek(item -> {
                item.setOwnerId(entity.getStaffId());
                item.setCreateUserId(this.getContextUserId(context));
                item.setCreateTime(new Date());
            }).count();
            windowOwnerDetailService.save(entity.getWindowOwnerDetailList());
        }
        super.saveAfter(entity, context);
    }

    @Override
    protected void updateAfter(WindowOwnerEntity entity, Context context) throws AppException {
        if (!ObjectUtils.isEmpty(entity.getWindowOwnerDetailList())) {
            Long[] windowOwnerDetailIds = windowOwnerDetailService.find(new WindowOwnerDetailQuery().ownerId(entity.getStaffId())).stream().map(WindowOwnerDetailEntity::getId).toArray(Long[]::new);
            windowOwnerDetailService.remove(windowOwnerDetailIds, context);
            entity.getWindowOwnerDetailList().stream().peek(item -> {
                item.setOwnerId(entity.getStaffId());
                item.setCreateUserId(this.getContextUserId(context));
                item.setCreateTime(new Date());
                item.setUpdateUserId(this.getContextUserId(context));
                item.setUpdateTime(new Date());
            }).count();
            windowOwnerDetailService.save(entity.getWindowOwnerDetailList());
        }
        super.updateAfter(entity, context);
    }


    @Override
    public Rest<List<String>> getPerformMonthList(Context context) {
        Set<String> collectSet = new HashSet<>();
        //查询所有窗口汇总表
        WindowPerformQuery windowPerformQuery = new WindowPerformQuery();
        windowPerformQuery.setOwnerId(context.getUser().getCustomerId());
        windowPerformQuery.setOrderColList(Arrays.asList(new OrderCol("year", OrderCol.DESCENDING), new OrderCol("month", OrderCol.DESCENDING)));
        Map<String, List<WindowPerformEntity>> collect = windowPerformService.find(windowPerformQuery).stream().collect(Collectors.groupingBy(item -> item.getYear() + "-" + item.getMonth()));
        Set<String> performMonthSet = collect.keySet();
        collectSet.addAll(performMonthSet);

        //查询所有窗口人员汇总表
        WindowWorkmanPerformQuery windowWorkmanPerformQuery = new WindowWorkmanPerformQuery();
        windowWorkmanPerformQuery.setOwnerId(context.getUser().getCustomerId());
        Map<String, List<WindowWorkmanPerformEntity>> workmanMonthSet = windowWorkmanPerformService.find(windowWorkmanPerformQuery).stream().collect(Collectors.groupingBy(item -> item.getYear() + "-" + item.getMonth()));
        collectSet.addAll(workmanMonthSet.keySet());

        //perform 排序 降序
        List<String> dateList = collectSet.stream().collect(Collectors.toList());
        Collections.sort(dateList, new Comparator<String>() {
            @Override
            public int compare(String object1, String object2) {
                return object1.compareTo(object2);
            }
        });

        return Rest.ok(dateList);
    }


    @Override
    protected void removeBefore(Long[] ids, Context context) throws AppException {
        super.removeBefore(ids, context);
        //删除窗口人员
        WindowOwnerQuery windowOwnerQuery = new WindowOwnerQuery();
        windowOwnerQuery.setIdList(Arrays.asList(ids));

        List<WindowOwnerEntity> windowOwnerEntities = this.find(windowOwnerQuery);
        List<Long> collect = windowOwnerEntities.stream().map(item -> item.getStaffId()).collect(Collectors.toList());
        if (!ObjectUtils.isEmpty(collect)) {
            WindowOwnerDetailQuery detailQuery = new WindowOwnerDetailQuery();
            detailQuery.ownerIdList(collect);
            Long[] delIds = windowOwnerDetailService.find(detailQuery).stream().map(item -> item.getId()).toArray(Long[]::new);
            if (!ObjectUtils.isEmpty(delIds)) {
                windowOwnerDetailService.remove(delIds, context);
            }
        }

    }

    @Override
    protected void findAfter(WindowOwnerEntity params, PageInfo pageInfo, Context context, List<WindowOwnerEntity> list) throws AppException {
        if(CollectionUtils.isNotEmpty(list)){
            list.forEach(item->{
                if(StringUtils.isNotEmpty(item.getStaffIds())){
                    List<Long> staffIdList = Arrays.asList(item.getStaffIds().split(",")).stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
                    item.setStaffIdList(staffIdList);
                    item.setStaffCount(staffIdList.size());
                }else {
                    item.setStaffIdList(Collections.emptyList());
                    item.setStaffCount(0);
                }
            });
        }
    }

    @Override
    public WindowOwnerEntity get(Long key, Context context) throws AppException {
        WindowOwnerEntity entity = this.dao.get(key);
        if(entity!=null){
            if(StringUtils.isNotEmpty(entity.getStaffIds())){
                List<Long> staffIdList = Arrays.asList(entity.getStaffIds().split(",")).stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
                entity.setStaffIdList(staffIdList);
                entity.setStaffCount(staffIdList.size());
            }else {
                entity.setStaffIdList(Collections.emptyList());
                entity.setStaffCount(0);
            }
        }
        return entity;
    }

    @Override
    public List<StaffErrorMessageVo> getStaffList(Long key) {
        WindowOwnerEntity entity = this.dao.get(key);
        List<StaffErrorMessageVo> result = new ArrayList<>();
        if(entity!=null){
            if(StringUtils.isNotEmpty(entity.getStaffIds())){
                List<Long> staffIdList = Arrays.asList(entity.getStaffIds().split(",")).stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
                List<PerformErrorMessageEntity> errorMessageList = performErrorMessageService.find(new PerformErrorMessageQuery().staffIdList(staffIdList));
                Map<Long,List<PerformErrorMessageEntity>> msgMap = errorMessageList.stream().collect(Collectors.groupingBy(PerformErrorMessageEntity::getStaffId));
                List<StaffEntity> staffEntityList = staffService.find(new StaffQuery().idList(staffIdList));
                for(StaffEntity staffEntity:staffEntityList){
                    StaffErrorMessageVo vo = new StaffErrorMessageVo();
                    BeanUtils.copyProperties(staffEntity, vo, BeanUtil.getNullPropertyNames(staffEntity));
                    vo.setStaffId(staffEntity.getId());
                    vo.setStaffName(staffEntity.getName());
                    if(msgMap.containsKey(staffEntity.getId())){
                        vo.setMessageCount(msgMap.get(staffEntity.getId()).size());
                    }else {
                        vo.setMessageCount(0);
                    }
                    result.add(vo);
                }
            }
        }
        return result;
    }
}