package cn.com.countrygarden.bi.main.service.ck.impl;

import cn.com.countrygarden.bi.main.core.Response;
import cn.com.countrygarden.bi.main.core.Result;
import cn.com.countrygarden.bi.main.dao.ShareConfigMapper;
import cn.com.countrygarden.bi.main.dao.ck.CkPublicBenefitsMapper;
import cn.com.countrygarden.bi.main.dao.ck.CkPublicBenefitsZationMapper;
import cn.com.countrygarden.bi.main.dao.sys.UserRolesMapper;
import cn.com.countrygarden.bi.main.dao.twerp.hm.TbSysOrganMapper;
import cn.com.countrygarden.bi.main.dto.CkPublicBenefitsDTOVO;
import cn.com.countrygarden.bi.main.dto.CkPublicBenefitsVO;
import cn.com.countrygarden.bi.main.dto.advise.ProjectListVO;
import cn.com.countrygarden.bi.main.dto.advise.RegionListVO;
import cn.com.countrygarden.bi.main.dto.ck.CkPublicBenefitsDTO;
import cn.com.countrygarden.bi.main.dto.ck.CkRegionVo;
import cn.com.countrygarden.bi.main.exception.ServiceException;
import cn.com.countrygarden.bi.main.model.AccessToken;
import cn.com.countrygarden.bi.main.model.PageData;
import cn.com.countrygarden.bi.main.model.ShareConfig;
import cn.com.countrygarden.bi.main.model.ck.CkPublicBenefits;
import cn.com.countrygarden.bi.main.model.ck.CkPublicBenefitsZation;
import cn.com.countrygarden.bi.main.model.sys.UserRoles;
import cn.com.countrygarden.bi.main.service.ck.CkPublicBenefitsService;
import cn.com.countrygarden.bi.main.util.MD5;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import net.sf.json.JSONObject;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Condition;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *   公共收益数据表业务处理
 * </p>
 *
 * @author 吕伟峰
 * @date 2021-05-07
 * @version V1.0
 */
@Transactional(rollbackFor =Exception.class)
@Service
public class CkPublicBenefitsServiceImpl implements CkPublicBenefitsService {
    @Autowired
    private CkPublicBenefitsMapper ckPublicBenefitsMapper;

    @Autowired
    private TbSysOrganMapper tbSysOrganMapper;

    @Autowired
    private UserRolesMapper userRolesMapper;

    @Autowired
    private CkPublicBenefitsZationMapper ckPublicBenefitsZationMapper;

    @Autowired
    private ShareConfigMapper shareConfigMapper;

    @Override
    public Result queryPageList(CkPublicBenefits ckPublicBenefits, int size,int page,AccessToken accessToken) {
        List<String> organCodeString=new ArrayList<>();
        List<String> commIdString=new ArrayList<>();
        String addrole=null;
        List<String> rolesList = queryRoleCodes(null, accessToken.getUserCode());
        if (rolesList.contains("ck_public_benefits_region")|| rolesList.contains("ck_public_benefits_project")|| rolesList.contains("ck_public_benefits_admin")
                || rolesList.contains("admin")){
            if(rolesList.contains("ck_public_benefits_region")|| rolesList.contains("ck_public_benefits_project")){
                List<RegionListVO> areaList = tbSysOrganMapper.findArea(null, accessToken.getUserCode());
                for (int i = 0; i < areaList.size(); i++) {
                    organCodeString.add(areaList.get(i).getOrganCode());
                    List<ProjectListVO> projectList = tbSysOrganMapper.findProject(areaList.get(i).getOrganCode(),accessToken.getUserCode(),null,null,null);
                    for (int j = 0; j <projectList.size() ; j++) {
                        commIdString.add(projectList.get(j).getCommId());
                    }
                }
            }
        }else {
            throw new ServiceException("此账号没有权限查看");
        }

        Page<Object> pageList = PageHelper.startPage(page, size);
        List<CkPublicBenefitsDTO> list=ckPublicBenefitsMapper.queryPageList(ckPublicBenefits,organCodeString,commIdString);
        PageData data = new PageData(pageList);
        data.setData(list);
        return Response.response(data);
    }

    @Override
    public List<RegionListVO> getRegionDate(AccessToken accessToken) {
        List<String> rolesList = queryRoleCodes(null, accessToken.getUserCode());
        List<RegionListVO> areaList = null;
        List<CkRegionVo> ckRegionVoList = new ArrayList<>();
        CkRegionVo ckRegionVo = null;
        List<ProjectListVO> projectList = null;
        List<ProjectListVO> projects = null;

        areaList = tbSysOrganMapper.findAreaBene(null, accessToken.getUserCode());

        return areaList;
    }

    @Override
    public List<ProjectListVO> getPojDate(AccessToken accessToken, String organCode) {
        String userCode=null;
        List<String> rolesList = queryRoleCodes(null, accessToken.getUserCode());
        List<ProjectListVO> projectList = tbSysOrganMapper.findProjectBenefits(organCode,accessToken.getUserCode(),null,null,null);
        return projectList;
    }

    @Override
    public Result add(CkPublicBenefits ckPublicBenefits, AccessToken accessToken) throws ParseException {
        CkPublicBenefitsZation ckPublicBenefitsZation=new CkPublicBenefitsZation();
        ckPublicBenefitsZation.setStatus(1);
        ckPublicBenefitsZation.setOrgCode(ckPublicBenefits.getOrgCode());
        ckPublicBenefitsZation.setCommCode(ckPublicBenefits.getCommCode());
        CkPublicBenefitsZation ckPunefits=ckPublicBenefitsZationMapper.selectOne(ckPublicBenefitsZation);
        if(ckPunefits==null){
            throw new ServiceException("此项目还未初始化数据，请先初始化！");
        }

        CkPublicBenefits ckPublic=new CkPublicBenefits();
        ckPublic.setStatus(1);
        ckPublic.setOrgCode(ckPublicBenefits.getOrgCode());
        ckPublic.setCommCode(ckPublicBenefits.getCommCode());
        ckPublic.setYear(ckPublicBenefits.getYear());
        ckPublic.setMonth(ckPublicBenefits.getMonth());
        CkPublicBenefits benefits=ckPublicBenefitsMapper.selectOne(ckPublic);
        if(benefits!=null){
            throw new ServiceException("请勿添加重复数据！");
        }
        Calendar a = Calendar.getInstance();
        ckPublicBenefits.setYearday(LocalDate.of(ckPublic.getYear(),1,1).lengthOfYear());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        a.setTime(sdf.parse(ckPublic.getYear()+"-"+ckPublic.getMonth()));
        ckPublicBenefits.setMonthday(a.getActualMaximum(Calendar.DAY_OF_MONTH));
        ckPublicBenefits.setStatus(1);
        ckPublicBenefits.setIsAuto(0);
        ckPublicBenefits.setCreateBy(accessToken.getUserCode());
        ckPublicBenefits.setUpdateBy(accessToken.getUserCode());
        ckPublicBenefits.setCreateTime(new Date());
        ckPublicBenefits.setUpdateTime(new Date());
        ckPublicBenefitsMapper.insert(ckPublicBenefits);
        return Response.response();
    }

    @Override
    public Result del(Integer id, AccessToken accessToken) {
        CkPublicBenefits ckPublicBenefits=new CkPublicBenefits();
        ckPublicBenefits.setId(id);
        ckPublicBenefits.setStatus(0);
        ckPublicBenefitsMapper.updateByPrimaryKeySelective(ckPublicBenefits);
        return Response.response();
    }

    @Override
    public Result one(Integer id, AccessToken accessToken) {
        return Response.response(ckPublicBenefitsMapper.seletcOnt(id));
    }

    @Override
    public Result edit(CkPublicBenefits ckPublicBenefits, AccessToken accessToken) {
        ckPublicBenefits.setUpdateTime(new Date());
        ckPublicBenefits.setUpdateBy(accessToken.getUserCode());
        ckPublicBenefitsMapper.updateByPrimaryKeySelective(ckPublicBenefits);
        return Response.response();
    }

    @Override
    public Result auto(String orgCode,String commCode,String createName,String year,AccessToken accessToken) throws ParseException {
        /*String[] idsStr=ids.split(",");
        List<String> idlist= Arrays.asList(idsStr);*/
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        Calendar a = Calendar.getInstance();

        CkPublicBenefits pu=new CkPublicBenefits();
        pu.setStatus(1);
        pu.setOrgCode(orgCode);
        pu.setCommCode(commCode);
        pu.setYear(Integer.valueOf(year));
        List<CkPublicBenefits> list=ckPublicBenefitsMapper.select(pu);
        for (int i = 0; i < list.size(); i++) {
            CkPublicBenefits ckPub=new CkPublicBenefits();
            ckPub.setId(list.get(i).getId());
            ckPub.setIsAuto(1);
            ckPublicBenefitsMapper.updateByPrimaryKeySelective(ckPub);

            List<CkPublicBenefits> addlist=new ArrayList<>();
            for (int j = 1; j <=12 ; j++) {
                CkPublicBenefits publicBenefits=new CkPublicBenefits();
                publicBenefits.setOrgCode(list.get(i).getOrgCode());
                publicBenefits.setOrgName(list.get(i).getOrgName());
                publicBenefits.setCommCode(list.get(i).getCommCode());
                publicBenefits.setCommName(list.get(i).getCommName());
                publicBenefits.setYear(list.get(i).getYear());
                publicBenefits.setMonth(j);
                publicBenefits.setStatus(1);
                CkPublicBenefits benefits=ckPublicBenefitsMapper.selectOne(publicBenefits);
                if(benefits!=null){
                    continue;
                }
                a.setTime(sdf.parse(publicBenefits.getYear()+"-"+publicBenefits.getMonth()));
                publicBenefits.setYearday(LocalDate.of(Integer.valueOf(publicBenefits.getYear()),1,1).lengthOfYear());
                publicBenefits.setMonthday(a.getActualMaximum(Calendar.DAY_OF_MONTH));
                publicBenefits.setStatus(1);
                publicBenefits.setIsAuto(1);
                publicBenefits.setUct(list.get(i).getUct());
                publicBenefits.setEdutax(list.get(i).getEdutax());
                publicBenefits.setLedtax(list.get(i).getLedtax());
                publicBenefits.setOther(list.get(i).getOther());
                publicBenefits.setBacirate(list.get(i).getBacirate());
                publicBenefits.setCreateBy(accessToken.getUserCode());
                publicBenefits.setCreateTime(new Date());
                publicBenefits.setUpdateTime(new Date());
                publicBenefits.setUpdateBy(accessToken.getUserCode());
                publicBenefits.setCreateName(createName);
                publicBenefits.setUpdateName(createName);
                addlist.add(publicBenefits);
            }
            if(addlist.size()!=0){
                ckPublicBenefitsMapper.insertList(addlist);
            }
        }
        return Response.response();
    }

    @Override
    public Result getrevenue(AccessToken accessToken, HttpServletRequest request) throws IOException {
        BufferedReader bufferReader = new BufferedReader(request.getReader());
        StringBuffer sbder = new StringBuffer();
        String line = null;
        while ((line = bufferReader.readLine()) != null) {
            sbder.append(line);
        }
        if(sbder==null || sbder.length()==0){
            return Response.responseFail("请输入参数");
        }
        JSONObject json = JSONObject.fromObject(sbder.toString());
        Map<String,Object> map=new HashMap<String,Object>();
        map.put("clientId",json.getString("clientId"));
        map.put("timeString",json.getString("timeString"));
        map.put("sign",json.getString("sign"));
        Result result = checkIdentity(json.getString("clientId"), json.getString("timeString"), json.getString("sign"));
        int code = result.getResultCode();
        if(500 == code){
            return result;
        }
        SimpleDateFormat sb=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date parse = sb.parse(json.getString("updateDate"));
        }catch (Exception e){
            return Response.responseFail("参数错误:updateDate时间格式有误");
        }

        List<CkPublicBenefitsVO> ckPublicBenefitsVOList=new ArrayList<>();
        List<CkPublicBenefitsVO> list=new ArrayList<>();
        List<CkPublicBenefitsDTOVO> revenueList=ckPublicBenefitsMapper.revenueList(json.getString("updateDate"));
        for (int i = 0; i < revenueList.size(); i++) {
            CkPublicBenefitsZation ckPublicBenefits=new CkPublicBenefitsZation();
            ckPublicBenefits.setStatus(1);
            ckPublicBenefits.setOrgCode(revenueList.get(i).getOrgCode());
            ckPublicBenefits.setCommCode(revenueList.get(i).getCommCode());
            //ckPublicBenefits.setYear(Integer.valueOf(revenueList.get(i).getYear()));
            revenueList.get(i).setUct(String.valueOf(Double.valueOf(revenueList.get(i).getUct())/100));
            revenueList.get(i).setEdutax(String.valueOf(Double.valueOf(revenueList.get(i).getEdutax())/100));
            revenueList.get(i).setOther(String.valueOf(Double.valueOf(revenueList.get(i).getOther())/100));
            revenueList.get(i).setBacirate(String.valueOf(Double.valueOf(revenueList.get(i).getBacirate())/100));
            revenueList.get(i).setLedtax(String.valueOf(Double.valueOf(revenueList.get(i).getLedtax())/100));
            CkPublicBenefitsZation ckPunefits=ckPublicBenefitsZationMapper.selectOne(ckPublicBenefits);
            if(ckPunefits==null){
                System.out.println(ckPublicBenefits.toString());
            }
            if(ckPunefits!=null){
                CkPublicBenefitsVO vo=new CkPublicBenefitsVO();
                vo.setOrgCode(ckPunefits.getOrgCode());
                vo.setOrgName(ckPunefits.getOrgName());
                vo.setCommCode(ckPunefits.getCommCode());
                vo.setCommName(ckPunefits.getCommName());
                vo.setBookTime(ckPunefits.getBookTime());
                vo.setUncollected(ckPunefits.getUncollected());
                vo.setAobamount(ckPunefits.getAobamount());
                vo.setPayablebut(ckPunefits.getPayablebut());
                ckPublicBenefitsVOList.add(vo);
            }

        }
        LinkedHashSet<CkPublicBenefitsVO> hashSet = new LinkedHashSet<>(ckPublicBenefitsVOList);
        list.addAll(hashSet);
        for (int i = 0; i <list.size() ; i++) {
            List<CkPublicBenefitsDTOVO> benefitsList=new ArrayList<>();
            for (int j = 0; j <revenueList.size() ; j++) {
                if(revenueList.get(j).getCommCode().equals(list.get(i).getCommCode())){
                    CkPublicBenefitsDTOVO benefits=revenueList.get(j);
                    benefitsList.add(benefits);
                    list.get(i).setPublicBenefitsList(benefitsList);
                }
            }
        }
        return Response.response(list);
    }


    //身份认证
    public Result checkIdentity(String clientId, String timeString, String sign){
        ShareConfig share=new ShareConfig();
        share.setClientId(clientId);
        ShareConfig shareConfig = shareConfigMapper.selectOne(share);
        if(shareConfig ==null){
            return Response.responseFail("认证失败:客户端编码有误");
        }
        String clientSecret = shareConfig.getClientSecret();
        SimpleDateFormat sb=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            String sd = sb.format(new Date(Long.valueOf(timeString+"000")));
            Date parse = sb.parse(sd);
            Date date=new Date();
            long l = date.getTime() - parse.getTime();
            if(l>5*60*1000){
                return Response.responseFail("参数错误:调用时间与参数时间不能超过5分钟");
            }
        }catch (Exception e){
            return Response.responseFail("参数错误:timeString格式有误");
        }

        String md5String =clientId+clientSecret+timeString;
        String s = MD5.GetMD5Code(md5String);
        if(!s.equals(sign)){
            return Response.responseFail("认证失败:签名错误");
        }
       return Response.response("认证成功");
    }



    public List<String> queryRoleCodes(String[] roles, String userCode) {
        //保洁模块的权限问题：admin=ck_admin>区域>项目>其他
        Condition condition = new Condition(UserRoles.class);
        condition.selectProperties("roleCode");
        Example.Criteria criteria = condition.createCriteria();
        criteria.andEqualTo("userCode", userCode);
        if (roles != null && roles.length > 0) {
            criteria.andIn("roleCode", Arrays.asList(roles));
        }

        List<UserRoles> rolesList = userRolesMapper.selectByCondition(condition);
        if (CollectionUtils.isNotEmpty(rolesList)) {
            return rolesList.stream().map(e -> e.getRoleCode()).collect(Collectors.toList());
        }
        // 权限不足
        throw new ServiceException("权限不足");
    }
}
