package com.jpsoft.shinestar.modules.base.service.impl;

import cn.hutool.core.util.IdcardUtil;
import com.alipay.api.domain.Person;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.jpsoft.shinestar.config.WxConfig;
import com.jpsoft.shinestar.modules.base.dao.PersonInfoDAO;
import com.jpsoft.shinestar.modules.base.entity.*;
import com.jpsoft.shinestar.modules.base.service.*;
import com.jpsoft.shinestar.modules.common.dto.Sort;
import com.jpsoft.shinestar.modules.common.utils.JwtUtil2;
import com.jpsoft.shinestar.modules.common.utils.WechatMessageUtil;
import com.jpsoft.shinestar.modules.sys.dao.SysLogDAO;
import com.jpsoft.shinestar.modules.sys.entity.SysLog;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

@Transactional
@Component(value = "personInfoService")
@Slf4j
public class PersonInfoServiceImpl implements PersonInfoService {
    @Resource(name = "personInfoDAO")
    private PersonInfoDAO personInfoDAO;

    @Autowired
    private SysLogDAO sysLogDAO;

    @Autowired
    private DeviceInfoService deviceInfoService;

    @Autowired
    private CompanyInfoService companyInfoService;

    @Autowired
    private WxConfig wxConfig;

    @Value("${jwt.secret}")
    private String jwtSecret;

    @Autowired
    private PersonRoleIconService personRoleIconService;

    @Autowired
    private PersonDeviceRelationService personDeviceRelationService;

    @Autowired
    private PersonPopedomService personPopedomService;

    @Autowired
    private PersonRoleInfoService personRoleInfoService;

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Override
    public PersonInfo get(Long id) {
        // TODO Auto-generated method stub
        return personInfoDAO.get(id);
    }

    @Override
    public int insert(PersonInfo model) {
        // TODO Auto-generated method stub
        //model.setId(UUID.randomUUID().toString());

        return personInfoDAO.insert(model);
    }

    @Override
    public int update(PersonInfo model) {
        // TODO Auto-generated method stub

        //每次修改人员信息时，增加日志记录工作状态
        SysLog sysLog = new SysLog();
        sysLog.setPointcut("人员信息修改");
        sysLog.setUserId(String.valueOf(model.getUpdateBy()));
        sysLog.setCreateTime(new Date());
        sysLog.setData(String.valueOf(model.getId()));

        PersonInfo srcPersonInfo = personInfoDAO.get(model.getId());
        sysLog.setRemark("人员编号:" + model.getId() + ",工作状态:" + srcPersonInfo.getWorkStatus() + "->" + model.getWorkStatus());

        sysLogDAO.insert(sysLog);

        return personInfoDAO.update(model);
    }

    @Override
    public int delete(Long id) {
        // TODO Auto-generated method stub
        return personInfoDAO.delete(id);
    }

    @Override
    public boolean exist(Long id) {
        // TODO Auto-generated method stub
        int count = personInfoDAO.exist(id);

        return count > 0 ? true : false;
    }

    @Override
    public List<PersonInfo> list() {
        // TODO Auto-generated method stub
        return personInfoDAO.list();
    }

    @Override
    public Page<PersonInfo> pageSearch(Map<String, Object> searchParams, int pageNumber, int pageSize, boolean count, List<Sort> sortList) {
        Page<PersonInfo> page = PageHelper.startPage(pageNumber, pageSize, count).doSelectPage(() -> {
            personInfoDAO.search(searchParams, sortList);
        });

        return page;
    }

    @Override
    public Page<PersonInfo> pageSearchNew(Map<String, Object> searchParams, int pageNumber, int pageSize, boolean count, List<Sort> sortList) {
        Page<PersonInfo> page = PageHelper.startPage(pageNumber, pageSize, count).doSelectPage(() -> {
            personInfoDAO.searchNew(searchParams, sortList);
        });

        return page;
    }

    @Override
    public PersonInfo findByNameAndPhone(String name, String phone) {
        return personInfoDAO.findByNameAndPhone(name, phone);
    }

    @Override
    public PersonInfo findByOpenId(String openId) {
        return personInfoDAO.findByOpenId(openId);
    }

    @Override
    public List<PersonInfo> findByCompanyId(String companyId) {
        return personInfoDAO.findByCompanyId(companyId);
    }

    @Override
    public List<PersonInfo> findListByCompanyCode(String companyCode){
        return personInfoDAO.findListByCompanyCode(companyCode);
    }

    @Override
    public List<PersonInfo> findByCompanyIdAndPopedom(String type, String companyId) {
        return personInfoDAO.findByCompanyIdAndPopedom(type, companyId);
    }

    @Override
    public long countByCompanyCode(String code, Long relatePersonId) {
        return personInfoDAO.countByCompanyCode(code, relatePersonId);
    }

    @Override
    public List<PersonInfo> findByCompanyCode(Map<String, Object> searchParams, List<Sort> sortList) {
        return personInfoDAO.findByCompanyCode(searchParams, sortList);
    }

    @Override
    public List<PersonInfo> findByUpdateHealthyTime(Date startDate, int limit) {
        return personInfoDAO.findByUpdateHealthyTime(startDate, limit);
    }

    @Override
    public long countByCompanyList(List<CompanyInfo> list) {
        return personInfoDAO.countByCompanyList(list);
    }

    @Override
    public long countByCompanyListAndPopedom(String type, List<CompanyInfo> list) {
        if ("teacher".equals(type)) {
            return personInfoDAO.countByCompanyListAndPopedom("%2%", list);
        }
        if ("student".equals(type)) {
            return personInfoDAO.countStudentByCompanyListAndPopedom("1", list);
        }
        return 0L;
    }

    @Override
    public PersonInfo findById(long longValue) {
        return personInfoDAO.findById(longValue);
    }

    @Override
    public PersonInfo getIgnoreDelFlag(Long id) {
        return personInfoDAO.getIgnoreDelFlag(id);
    }

    @Override
    public long countByCompanyId(String companyId) {
        return personInfoDAO.countByCompanyId(companyId);
    }

    @Override
    public long countByCompanyIds(List<String> companyIds) {
        return personInfoDAO.countByCompanyIds(companyIds);
    }

    @Override
    public PersonInfo addPersonForCompany(PersonInfo personInfo, String deviceNo) {

        if (StringUtils.isNotBlank(personInfo.getName()) && StringUtils.isNotBlank(personInfo.getIdCard()) && personInfo.getId() == 0) {
            DeviceInfo deviceInfo = deviceInfoService.getByDeviceNo(deviceNo);
            if (deviceInfo != null) {
                PersonInfo personInfo1 = personInfoDAO.findByIdCardAndCompanyId(personInfo.getIdCard(), deviceInfo.getCompanyId());
                if (personInfo1 == null) {
                    PersonInfo personInfo2 = new PersonInfo();
                    personInfo2.setCompanyId(deviceInfo.getCompanyId());
                    personInfo2.setName(personInfo.getName());
                    personInfo2.setIdCard(personInfo.getIdCard());
                    personInfo2.setDelFlag(false);
                    personInfo2.setCreateTime(new Date());
                    personInfo2.setPopedom("1");
                    personInfo2.setWechatNoticeEnabled(false);
                    personInfo2.setAllowViewLocal(false);
                    personInfo2.setGuestEnabled(true);
                    personInfoDAO.insert(personInfo2);
                    return personInfo2;
                } else {
                    return personInfo1;
                }


            } else {
                return personInfo;
            }


        } else {
            return personInfo;
        }
    }

    @Override
    public long notGuestList() {
        return personInfoDAO.notGuestList();
    }

    @Override
    public int resetOpenId(Long personId) {
        return personInfoDAO.resetOpenId(personId);
    }

    @Override
    public int updateHealthyCode(PersonInfo personInfo) {
        return personInfoDAO.updateHealthyCode(personInfo);
    }

    @Override
    public List<Map> groupByHealthyCode(Map<String, Object> searchParams) {
        return personInfoDAO.groupByHealthyCode(searchParams);
    }

    @Override
    public List<Map> groupHealthyById(List<Long> idList) {
        return personInfoDAO.groupHealthyById(idList);
    }

    @Override
    public PersonInfo findByPhone(String phone) {

        return personInfoDAO.findByPhone(phone);
    }

    @Override
    public List<Long> findByOrderProperty(Map<String, Object> searchParams) {
        return personInfoDAO.findByOrderProperty(searchParams);
    }

    @Override
    public Long insertPersonAndPopedom(PersonApplicationInfo personApplicationInfo, String deviceIds, String companyId) throws Exception {

        PersonInfo person = null;
        Long personId = null;

        PersonInfo personInfo0 = findByPhone(personApplicationInfo.getTelephone());
        if (personInfo0 != null) {
            personApplicationInfo.setPersonId(personInfo0.getId());
        }

        //新用户处理
        if (personApplicationInfo.getPersonId() == null) {
            PersonInfo personInfo = new PersonInfo();

            if (StringUtils.isNotBlank(companyId)) {
                personInfo.setCompanyId(companyId);
            } else {
                personInfo.setCompanyId(personApplicationInfo.getCompanyId());
            }
            personInfo.setName(personApplicationInfo.getName());
            personInfo.setIdCard(personApplicationInfo.getIdCard());
            personInfo.setOpenId(personApplicationInfo.getOpenId());
            personInfo.setPhone(personApplicationInfo.getTelephone());
            personInfo.setGuestEnabled(false);
            personInfo.setDelFlag(false);
            personInfo.setFaceImageUrl(personApplicationInfo.getFaceImageUrl());
            personInfo.setCreateTime(new Date());
            personInfo.setCreateBy(personApplicationInfo.getExaminePopedomId());
            personInfo.setFaceEnabled(true);
            personInfo.setFaceBound(true);
            personInfo.setAppEnabled(true);
            personInfo.setWorkStatus("1");
            personInfo.setIsSync(false);
            if (org.apache.commons.lang3.StringUtils.isNotBlank(personApplicationInfo.getIdCard())) {
                try {
                    personInfo.setSex(String.valueOf(IdcardUtil.getGenderByIdCard(personApplicationInfo.getIdCard())));
                } catch (Exception ex) {
                    log.error(ex.getMessage());
                }

            }

            insert(personInfo);

            person = personInfo;
            personApplicationInfo.setPersonId(personInfo.getId());
            personId = personInfo.getId();
        }
        //老用户注册新身份
        else {
            personId = personApplicationInfo.getPersonId();
        }

        boolean enableInsert = true;
        List<PersonPopedom> personPopedomList = personPopedomService.findByPersonId(personId);
        if (personPopedomList.size() > 0) {
            for (PersonPopedom personPopedom : personPopedomList) {
                if (personApplicationInfo.getPersonRoleId().equals(personPopedom.getPersonRoleId()) && personApplicationInfo.getCompanyId().equals(personPopedom.getCompanyId())) {
                    enableInsert = false;
                    break;
                }
            }
        }

        if (enableInsert) {


            //查询申请的角色信息
            PersonRoleInfo personRoleInfo = personRoleInfoService.get(personApplicationInfo.getPersonRoleId());

            //写入注册的新身份
            PersonPopedom personPopedom = new PersonPopedom();
            personPopedom.setId(UUID.randomUUID().toString());

            if (StringUtils.isNotBlank(companyId)) {
                personPopedom.setCompanyId(companyId);
            } else {
                personPopedom.setCompanyId(personApplicationInfo.getCompanyId());
            }
            personPopedom.setPersonId(personApplicationInfo.getPersonId());
            personPopedom.setPersonRoleId(personApplicationInfo.getPersonRoleId());
            personPopedom.setShowIconId(personRoleIconService.getDefaultIcon(personApplicationInfo.getPersonRoleId()));
            personPopedom.setCompanyStructureId(personApplicationInfo.getStructureId());
            personPopedom.setCreateTime(new Date());
            personPopedom.setDelFlag(false);
            personPopedom.setEnableAttendance(true); //默认开启考勤
            personPopedom.setAddress(personApplicationInfo.getAddress());
            personPopedom.setServiceCompanyId(personApplicationInfo.getServiceCompanyId());
            personPopedom.setPopularizePersonId(personApplicationInfo.getPopularizePersonId());
            personPopedom.setWorkOverTime(0);
            personPopedom.setSceneId(personRoleInfo.getSceneId());
            personPopedomService.insert(personPopedom);

            //新用户绑定新身份
            if (person != null) {
                person.setPopedom(personPopedom.getId());
                update(person);
            }


            //人脸数据写入设备
            if (StringUtils.isNotBlank(deviceIds) && !"4".equals(personApplicationInfo.getSceneId())) {
                List<String> deviceList = Arrays.asList(deviceIds.split(","));
                for (String id : deviceList) {
                    //已存在的人员设备关联不重复写入
                    PersonDeviceRelation personDeviceRelation0 = personDeviceRelationService.findByDeviceIdAndPersonId(id, personId);
                    if (personDeviceRelation0 == null) {
                        PersonDeviceRelation personDeviceRelation = new PersonDeviceRelation();
                        personDeviceRelation.setId(UUID.randomUUID().toString());
                        personDeviceRelation.setDeviceId(id);
                        personDeviceRelation.setPersonId(personId);
                        personDeviceRelation.setCreateBy(personApplicationInfo.getUpdateBy());
                        personDeviceRelation.setDelFlag(false);
                        personDeviceRelation.setCreateTime(new Date());
                        personDeviceRelation.setIsBound(true);
                        personDeviceRelationService.insert(personDeviceRelation);
                    }
                }
            }

        }
        return personId;
    }

    @Override
    public void sendRegisterMessage(PersonApplicationInfo personApplicationInfo) {
        PersonRoleInfo personRoleInfo = personRoleInfoService.get(personApplicationInfo.getPersonRoleId());

        List<PersonPopedom> personPopedomList0 = personPopedomService.findByCompanyIdAndEnableRegisterExamine(personApplicationInfo.getCompanyId(), true);

        if (personPopedomList0.size() > 0) {
            for (PersonPopedom personPopedom : personPopedomList0) {
                PersonInfo personInfo = get(personPopedom.getPersonId());
                if (personInfo!=null && StringUtils.isNotBlank(personInfo.getOpenId()) && personInfo.getWechatNoticeEnabled()) {

                    String token = JwtUtil2.createToken(jwtSecret, personInfo.getId() + "", DateTime.now().plusHours(6).toDate());
                    WechatMessageUtil.sendEvenMessage(personInfo.getOpenId(), "有一条新的注册信息待审核", personApplicationInfo.getName(), personApplicationInfo.getId().substring(0, 5), "前往处理", wxConfig.getPortalUrl() + "master/company/registerExamine?exchange=1&role_id=" + personPopedom.getId() + "&token=" + token, wxConfig.getAppId(), wxConfig.getAppSecret());
                }
            }
        } else {
            String companyId = "";
            if (StringUtils.isNotBlank(personApplicationInfo.getServiceCompanyId())) {
                companyId = personApplicationInfo.getServiceCompanyId();
            } else {
                CompanyInfo companyInfo = companyInfoService.get(personApplicationInfo.getCompanyId());
                if (StringUtils.isNotBlank(companyInfo.getRelationCompanyId()) && "2".equals(companyInfo.getSceneId())) {
                    companyId = companyInfo.getRelationCompanyId();
                } else {
                    companyId = companyInfo.getId();
                }
            }

            CompanyInfo companyInfo = companyInfoService.get(companyId);


            List<PersonRoleIcon> personRoleIconList = personRoleIconService.findByIconName("注册审核");

            List<String> personRoloIds = new ArrayList<>();
            if (personRoleIconList.size() > 0) {
                for (PersonRoleIcon personRoleIcon : personRoleIconList) {
                    personRoloIds.add(personRoleIcon.getPersonRoleId());
                }
            }

            List<String> companyIdList = new ArrayList<>();
            companyIdList.add(companyId);

            Page<PersonPopedom> personPopedomPage = new Page<>();

            Map<String, Object> searchParams = new HashMap<>();
            //    searchParams.put("inCompanyId",Arrays.asList(companyInfo.getCode().split(",")));
            searchParams.put("inCompanyId", companyIdList);
            searchParams.put("enableRegisterExamine", true);
            List<Sort> sortList = new ArrayList<>();
            sortList.add(new Sort("create_time", "desc"));
            personPopedomPage = personPopedomService.pageSearch(searchParams, 1, 10, false, sortList);
            if (personPopedomPage.getResult().size() == 0) {

                searchParams.put("inCompanyId", Arrays.asList(companyInfo.getCode().split(",")));

                searchParams.put("enableRegisterExamine", true);

                personPopedomPage = personPopedomService.pageSearch(searchParams, 1, 10, false, sortList);
            }


            List<PersonPopedom> personPopedomList = personPopedomPage.getResult();

            if (personPopedomList.size() > 0) {
                for (PersonPopedom personPopedom : personPopedomList) {
                    PersonInfo personInfo = get(personPopedom.getPersonId());
                    if (StringUtils.isNotBlank(personInfo.getOpenId()) && personInfo.getWechatNoticeEnabled()) {

                        String token = JwtUtil2.createToken(jwtSecret, personInfo.getId() + "", DateTime.now().plusHours(6).toDate());
                        WechatMessageUtil.sendEvenMessage(personInfo.getOpenId(), "有一条新的注册信息待审核", personApplicationInfo.getName(), personApplicationInfo.getId().substring(0, 5), "前往处理", wxConfig.getPortalUrl() + "master/company/registerExamine?exchange=1&role_id=" + personPopedom.getId() + "&token=" + token, wxConfig.getAppId(), wxConfig.getAppSecret());
                    }
                }
            }

        }
    }

    @Override
    public void sendParkingMessage(ParkingApply parkingApply) {

        List<PersonRoleIcon> personRoleIconList = personRoleIconService.findByIconName("车位申请记录");

        PersonPopedom personPopedom0 = personPopedomService.get(parkingApply.getPopedomId());
        PersonInfo personInfo0 = get(personPopedom0.getPersonId());

        List<String> personRoloIds = new ArrayList<>();
        if (personRoleIconList.size() > 0) {
            for (PersonRoleIcon personRoleIcon : personRoleIconList) {
                personRoloIds.add(personRoleIcon.getPersonRoleId());
            }
        }

        List<PersonPopedom> personPopedomList = personPopedomService.findByCompanyIdAndRoleIdList(parkingApply.getCompanyId(), personRoloIds);
        if (personPopedomList.size() > 0) {
            for (PersonPopedom personPopedom : personPopedomList) {
                PersonInfo personInfo = get(personPopedom.getPersonId());
                if (StringUtils.isNotBlank(personInfo.getOpenId()) && personInfo.getWechatNoticeEnabled()) {
                    String token = JwtUtil2.createToken(jwtSecret, personInfo.getId() + "", DateTime.now().plusHours(6).toDate());
                    WechatMessageUtil.sendEvenMessage(personInfo.getOpenId(), "有一条新的车位申请待审核", personInfo0.getName(), parkingApply.getId().substring(0, 5), "前往处理", wxConfig.getPortalUrl() + "master/Property/Car/info?id=" + parkingApply.getId() + "&exchange=1&role_id=" + personPopedom.getId() + "&token=" + token, wxConfig.getAppId(), wxConfig.getAppSecret());
                }
            }
        }
    }

    @Override
    public PersonInfo findByNameAndIdCard(String name, String idCard) {
        return personInfoDAO.findByNameAndIdCard(name, idCard);
    }

    @Override
    public Page<PersonInfo> searchCanteenOutsourcerBalance(Map<String, Object> searchParams, int pageNumber, int pageSize,boolean count,List<Sort> sortList){
        Page<PersonInfo> page = PageHelper.startPage(pageNumber,pageSize,count).doSelectPage(()->{
            personInfoDAO.searchCanteenOutsourcerBalance(searchParams,sortList);
        });

        return page;
    }

    @Override
    public PersonInfo findByIdIgnoreDel(Long personId) {
        return personInfoDAO.findByIdIgnoreDel(personId);
    }

    @Override
    public PersonInfo findByCarNum(String carNum) {
        return personInfoDAO.findByCarNum(carNum);
    }

    @Override
    public PersonInfo findJobNumber(String jobNumber) {
        return personInfoDAO.findJobNumber(jobNumber);
    }

    @Override
    public int updateNullForHqSortNo(Long personId){
        return personInfoDAO.updateNullForHqSortNo(personId);
    }

    @Override
    public List<PersonInfo> findByHq(){
        return personInfoDAO.findByHq();
    }

}