package nccloud.impl.hrkq.diwork;

import nc.bs.framework.common.NCLocator;
import nc.bs.logging.Logger;
import nc.hr.utils.InSQLCreator;
import nc.hr.utils.ResHelper;
import nc.hr.utils.StringPiecer;
import nc.itf.hr.frame.IPersistenceRetrieve;
import nc.itf.hr.org.IPrimaryOrgQry;
import nc.itf.org.IOrgConst;
import nc.itf.uap.IUAPQueryBS;
import nc.vo.org.DeptVO;
import nc.vo.org.OrgVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.SuperVO;
import nccloud.commons.collections.CollectionUtils;
import nccloud.commons.lang.StringUtils;
import nccloud.itf.hrkq.IHRKQQueryService;
import nccloud.pub.hrkq.util.IAttendCommonUtil;
import nccloud.pub.hrkq.util.StringListProcessor;
import nccloud.pubitf.baseapp.apprbac.IAppAndOrgPermQueryPubService;
import nccloud.vo.hrkq.attendance.AttendanceVO;
import nccloud.vo.hrkq.leave.LeaveVO;
import nccloud.vo.hrkq.leaveoff.LeaveoffVO;
import nccloud.vo.hrkq.outside.OutSideVO;
import nccloud.vo.hrkq.overtime.OverTimeVO;
import nccloud.vo.hrkq.trip.TripVO;
import nccloud.vo.hrkq.tripoff.TripoffVO;
import org.apache.commons.lang3.ArrayUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class HRKQQuerySerivceImpl implements IHRKQQueryService {

    @Override
    public List<String> queryPsnBillList(String billType, String order, String beginDate, String endDate,
                                         String pkPsndoc, String pkGroup, String userId, String appCode) throws BusinessException {
        // 定义查询条件
        StringBuffer where = new StringBuffer(" where 1=1 ");
        if (StringUtils.isNotEmpty(beginDate) || StringUtils.isNotEmpty(endDate)) {
            String dateSql = getDateFilterSql(billType, beginDate, endDate);
            if (StringUtils.isNotBlank(dateSql)) {
                where.append(dateSql);
            }
        }
        where.append(" and pk_psndoc ='" + pkPsndoc + "' ");
        return doQueryBillList(billType, where.toString(), order, pkGroup, userId, appCode);
    }

    @Override
    public List<String> queryDeptBillList(String billType, String order, String beginDate, String endDate,
                                          String pkDept, String psnName, String jobId, String pkGroup, String userId, String appCode, boolean isIncludeSub) throws BusinessException {
        StringBuffer where = genQuerySql(billType, beginDate, endDate, psnName, pkDept, jobId, isIncludeSub, getPowerDeptMap(userId, pkGroup, appCode));
        return doQueryBillList(billType, where.toString(), order, pkGroup, userId, appCode);
    }

    @Override
    public List<String> queryAdminBillList(String billType, String order, String beginDate, String endDate,
                                           String pkDept, String tempWhere, String pkGroup, String userId, String appCode) throws BusinessException {
        StringBuffer where = genQuerySql(billType, beginDate, endDate, null, pkDept, null, false, getPowerDeptMap(userId, pkGroup, appCode));
        // 权限组织条件
        String[] powerOrgIds = queryPowerOrgList(userId, pkGroup, appCode);
        if (ArrayUtils.isEmpty(powerOrgIds)) {
            return Collections.emptyList();
        }
        InSQLCreator inSqlCreator = new InSQLCreator();

        String strInSQL = inSqlCreator.getInSQL(powerOrgIds);

        where.append(" and pk_org in (" + strInSQL + ")");

        if (StringUtils.isNotBlank(tempWhere)) {
            where.append(" and " + tempWhere);
        }
        return doQueryBillList(billType, where.toString(), order, pkGroup, userId, appCode);
    }

    private StringBuffer genQuerySql(String billType, String beginDate, String endDate, String psnName, String pkDept,
                                     String jobId, boolean isIncludeSub, Map<String, String> deptMap) {
        // 在职条件过滤
        StringBuffer psnSqlIn = new StringBuffer();
        psnSqlIn.append("SELECT ");
        psnSqlIn.append("DISTINCT job.pk_psndoc ");
        psnSqlIn.append("FROM ");
        psnSqlIn.append("hi_psnjob job INNER JOIN BD_PSNDOC doc ON job.pk_psndoc = doc.pk_psndoc ");
        psnSqlIn.append("WHERE ");
        // 主任职
        psnSqlIn.append("job.ISMAINJOB = 'Y' ");
        // 生效记录
        psnSqlIn.append("AND job.lastflag = 'Y' ");
        // 职务过滤
        if (StringUtils.isNotBlank(jobId)) {
            String[] jobArray = jobId.split(",");
            InSQLCreator creator = new InSQLCreator();
            try {
                String jobInSql = creator.getInSQL(jobArray);
                psnSqlIn.append(" AND job.PK_JOB in (" + jobInSql + ") ");
            } catch (nc.vo.pub.BusinessException e) {
                Logger.error(e.getMessage(), e);
                throw new RuntimeException(ResHelper.getString("6020hrkq", "6020hrkq00023")
                        /*@res "职务查询异常" */);
            }
        }

        // 定义查询条件
        StringBuffer where = new StringBuffer(" where 1=1 ");
        if (StringUtils.isNotEmpty(beginDate) || StringUtils.isNotEmpty(endDate)) {
            String dateSql = getDateFilterSql(billType, beginDate, endDate);
            if (StringUtils.isNotBlank(dateSql)) {
                where.append(dateSql);
            }
        }
        // 人员姓名模糊条件
        if (StringUtils.isNotBlank(psnName)) {
            // 姓名模糊检索
            psnSqlIn.append("AND doc.name LIKE '%" + psnName + "%' ");
        }
        where.append(" and pk_psndoc in (" + psnSqlIn.toString() + ")");
        // 部门过滤
        if (StringUtils.isNotBlank(pkDept)) {
            if (isIncludeSub) {
                String strInSql = getChildrenDeptById(pkDept, deptMap);
                if (StringUtils.isNotEmpty(strInSql)) {
                    if (strInSql.startsWith("(")) {
                        where.append(" and pk_dept in " + strInSql);
                    } else {
                        where.append(" and pk_dept in (" + strInSql + ")");
                    }
                }
            } else {
                if (!deptMap.isEmpty() && deptMap.containsKey(pkDept)) {
                    where.append(" and pk_dept = '" + pkDept + "'");
                } else {
                    where.append(" and pk_dept = '#####'");
                }
            }
        } else if (deptMap != null && deptMap.size() > 0) {
            String[] powerDept = deptMap.keySet().toArray(new String[deptMap.size()]);
            InSQLCreator creator = new InSQLCreator();
            try {
                String inSQL = creator.getInSQL(powerDept);
                where.append(" AND pk_dept in (" + inSQL + ") ");
            } catch (nc.vo.pub.BusinessException e) {
                Logger.error(e.getMessage(), e);
                throw new RuntimeException(ResHelper.getString("6020hrkq", "6020hrkq00014")
                        /*@res "查询有权限部门异常" */);
            }
        }
        return where;
    }

    /**
     * 根据开始日期结束日期生成sql片段 因为每个单据的日期字段不一样，所以这样处理
     *
     * @param billType
     * @param beginDate
     * @param endDate
     * @return
     */
    private static String getDateFilterSql(String billType, String beginDate, String endDate) {
        StringBuffer dateSql = new StringBuffer();
        String beginDateField = "";
        String endDateField = "";
        switch (billType) {
            case IAttendCommonUtil.BILL_TYPE_LEAVE:
                beginDateField = LeaveVO.BEGINTIME;
                endDateField = LeaveVO.ENDTIME;
                break;

            case IAttendCommonUtil.BILL_TYPE_ATTENDANCE:
                beginDateField = AttendanceVO.FILL_DATE;
                break;

            case IAttendCommonUtil.BILL_TYPE_TRIPOFF:
                beginDateField = TripoffVO.TRIPOFFBEGINTIME;
                endDateField = TripoffVO.TRIPOFFENDTIME;
                break;

            case IAttendCommonUtil.BILL_TYPE_LEAVEOFF:
                beginDateField = LeaveoffVO.LEAVEOFFBEGINTIME;
                endDateField = LeaveoffVO.LEAVEOFFENDTIME;
                break;

            case IAttendCommonUtil.BILL_TYPE_OUTSIDE:
                beginDateField = OutSideVO.SIGNDATE;
                break;

            case IAttendCommonUtil.BILL_TYPE_OVERTIME:
                beginDateField = OverTimeVO.OVERTIMEBEGINTIME;
                endDateField = OverTimeVO.OVERTIMEENDTIME;
                break;
            case IAttendCommonUtil.BILL_TYPE_TRIP:
                beginDateField = TripVO.TRIPBEGINTIME;
                endDateField = TripVO.TRIPENDTIME;
                break;

            default:
                break;
        }
        dateSql.append(" and ( ");
        if (StringUtils.isNotEmpty(beginDateField)) {
            dateSql.append("( ");
            if (StringUtils.isNotBlank(beginDate)) {
                dateSql.append(beginDateField + " >= '" + beginDate + " 00:00:00' ");
            }
            if (StringUtils.isNotBlank(endDate)) {
                dateSql.append(" and " + beginDateField + " <= '" + endDate + " 23:59:59' ");
            }
            dateSql.append(") ");
        }
        if (StringUtils.isNotEmpty(endDateField)) {
            dateSql.append("or ( ");
            if (StringUtils.isNotBlank(beginDate)) {
                dateSql.append(endDateField + " >= '" + beginDate + " 00:00:00' ");
            }
            if (StringUtils.isNotBlank(endDate)) {
                dateSql.append(" and " + endDateField + " <= '" + endDate + " 23:59:59' ");
            }
            dateSql.append(") ");
        }
        if (StringUtils.isNotEmpty(beginDateField) && StringUtils.isNotEmpty(endDateField)) {
            dateSql.append("or (");
            if (StringUtils.isNotBlank(beginDate)) {
                dateSql.append(beginDateField + " <= '" + beginDate + " 00:00:00' ");
            }
            if (StringUtils.isNotBlank(endDate)) {
                dateSql.append(" and " + endDateField + " >= '" + endDate + " 23:59:59' ");
            }
            dateSql.append(") ");
        }
        dateSql.append(")");
        return dateSql.toString();
    }

    /**
     * 查询hr组织
     *
     * @return String[]
     * @throws BusinessException BusinessException
     */
    @SuppressWarnings("unchecked")
    private String[] queryOrgList() throws BusinessException {
        String sql = "select pk_adminorg from org_adminorg";
        List<String> orgList = (List<String>) NCLocator.getInstance().lookup(IUAPQueryBS.class).executeQuery(sql,
                new StringListProcessor());
        if (CollectionUtils.isEmpty(orgList)) {
            return null;
        }
        String[] pkOrgs = orgList.toArray(new String[0]);
        // 行政组织
        OrgVO[] orgVOs = NCLocator.getInstance().lookup(IPrimaryOrgQry.class)
                .queryPrimaryOrgVOs(IPrimaryOrgQry.CONTROLTYPE_ADMINORG, pkOrgs);

        return StringPiecer.getStrArray(orgVOs, OrgVO.PK_ORG);
    }


    /**
     * 查询有权限的组织
     *
     * @param userId userId
     * @param pkGroup pkGroup
     * @param appCode appCode
     * @return String[]
     */
    private String[] queryPowerOrgList(String userId, String pkGroup, String appCode) {
        try {
            String[] orgIds = NCLocator.getInstance().lookup(IAppAndOrgPermQueryPubService.class).queryUserPermOrgPksByAppAndWithOrgTypesFilter(userId,appCode,new String[]{IOrgConst.ADMINORGTYPE},pkGroup);
            if (orgIds == null || orgIds.length == 0) {
                return null;
            }
            InSQLCreator isc = new InSQLCreator();
            String strInSql = isc.getInSQL(orgIds);
            String sql = null;
            if(strInSql.startsWith("(")) {
                sql = "(select org_adminorg.pk_adminorg from org_adminorg inner join org_admin_enable on org_adminorg.pk_adminorg=org_admin_enable.pk_adminorg where org_adminorg.enablestate = 2 and org_adminorg.islastversion = 'Y' and org_adminorg.dr = 0 and org_adminorg.pk_adminorg in "+ strInSql + ")";
            } else {
                sql = "(select org_adminorg.pk_adminorg from org_adminorg inner join org_admin_enable on org_adminorg.pk_adminorg=org_admin_enable.pk_adminorg where org_adminorg.enablestate = 2 and org_adminorg.islastversion = 'Y' and org_adminorg.dr = 0 and org_adminorg.pk_adminorg in ("+ strInSql + "))";
            }
            List<String> powerOrgIds = (List<String>) NCLocator.getInstance().lookup(IUAPQueryBS.class).executeQuery(sql,
                    new StringListProcessor());
            if(CollectionUtils.isEmpty(powerOrgIds)) {
                return null;
            }
            return powerOrgIds.toArray(new String[0]);
        } catch (BusinessException e) {
            Logger.error(e.getMessage(), e);
        }
        return null;
    }


    @SuppressWarnings({"unchecked", "deprecation"})
    private List<String> doQueryBillList(String billType, String where, String order, String pkGroup, String userId, String appCode) throws BusinessException {
        // 按排序查询所有数据的pk
        StringBuffer sqlAll = new StringBuffer(" select ");
        SuperVO superVO = IAttendCommonUtil.beanMap.get(billType);
        String pkFieldName = superVO.getPKFieldName();
        String tableName = superVO.getTableName();
        sqlAll.append(pkFieldName + " ");
        sqlAll.append(" from ");
        sqlAll.append(tableName + " ");
        sqlAll.append(where);
        if (StringUtils.isNotBlank(pkGroup)) {
            sqlAll.append(" and pk_group = '" + pkGroup + "'");
        }
        if (StringUtils.isNotBlank(order)) {
            sqlAll.append(" order by " + order);
        }
        Logger.error("sqlAll:" + sqlAll);
        return (List<String>) NCLocator.getInstance().lookup(IUAPQueryBS.class).executeQuery(sqlAll.toString(),
                new StringListProcessor());
    }


    /**
     * 获取当前登录人有权限的部门
     *
     * @param userId  用户
     * @param PkGroup 集团
     * @param appCode appCode
     * @return 返回sql
     * @throws BusinessException
     */
    private String getPowerDeptCondition(String userId, String PkGroup, String appCode) throws BusinessException {
        IAppAndOrgPermQueryPubService service = NCLocator.getInstance().lookup(IAppAndOrgPermQueryPubService.class);

        String[] deptIds = service.queryUserPermOrgPksByAppAndWithOrgTypesFilter(userId, appCode, new String[]{IOrgConst.DEPTORGTYPE}, PkGroup);
        if (deptIds == null || deptIds.length == 0) {
            return null;
        }
        InSQLCreator isc = new InSQLCreator();
        String strInSql = null;
        try {
            strInSql = isc.getInSQL(deptIds);
        } catch (BusinessException e) {
            Logger.error(e.getMessage(), e);
            throw new RuntimeException(ResHelper.getString("6020hrkq", "6020hrkq00014")
                    /*@res "查询有权限部门异常！" */);
        }
        if (strInSql.startsWith("(")) {
            return "(select org_dept.pk_dept from org_dept inner join org_admin_enable on org_dept.pk_org=org_admin_enable.pk_adminorg where org_dept.hrcanceled<>'Y' and org_dept.pk_dept in " + strInSql + ")";
        } else {
            return "(select org_dept.pk_dept from org_dept inner join org_admin_enable on org_dept.pk_org=org_admin_enable.pk_adminorg where org_dept.hrcanceled<>'Y' and org_dept.pk_dept in (" + strInSql + "))";
        }
    }


    /**
     * 获取有权限部门map
     *
     * @param userId  userId
     * @param PkGroup pkGroup
     * @param appCode appCode
     * @return map
     * @throws BusinessException BusinessException
     */
    private Map<String, String> getPowerDeptMap(String userId, String PkGroup, String appCode) throws BusinessException {
        IAppAndOrgPermQueryPubService service = NCLocator.getInstance().lookup(IAppAndOrgPermQueryPubService.class);

        String[] deptIds = service.queryUserPermOrgPksByAppAndWithOrgTypesFilter(userId, appCode, new String[]{IOrgConst.DEPTORGTYPE}, PkGroup);
        if (deptIds == null || deptIds.length == 0) {
            return null;
        }
        InSQLCreator isc = new InSQLCreator();
        String strInSql = null;
        try {
            strInSql = isc.getInSQL(deptIds);
        } catch (BusinessException e) {
            Logger.error(e.getMessage(), e);
            throw new RuntimeException(ResHelper.getString("6020hrkq", "6020hrkq00014")
                    /*@res "查询有权限部门异常！" */);
        }
        String sql;
        if (strInSql.startsWith("(")) {
            sql = "(select org_dept.pk_dept from org_dept inner join org_admin_enable on org_dept.pk_org=org_admin_enable.pk_adminorg where org_dept.hrcanceled<>'Y' and org_dept.pk_dept in " + strInSql + ")";
        } else {
            sql = "(select org_dept.pk_dept from org_dept inner join org_admin_enable on org_dept.pk_org=org_admin_enable.pk_adminorg where org_dept.hrcanceled<>'Y' and org_dept.pk_dept in (" + strInSql + "))";
        }
        List<String> powerDeptIds = (List<String>) NCLocator.getInstance().lookup(IUAPQueryBS.class).executeQuery(sql,
                new StringListProcessor());
        Map<String, String> deptMap = new HashMap<>();
        for (String powerDeptId : powerDeptIds) {
            if (!deptMap.containsKey(powerDeptId)) {
                deptMap.put(powerDeptId, "1");
            }
        }
        if (deptMap.isEmpty()) {
            return null;
        }
        return deptMap;
    }


    /**
     * 查询部门的下级部门
     *
     * @param pkDept 部门id
     * @return string
     */
    private String getChildrenDeptById(String pkDept, Map<String, String> deptMap) {
        IPersistenceRetrieve persistenceRetrieve = NCLocator.getInstance().lookup(IPersistenceRetrieve.class);
        SuperVO deptVO;
        String strInSql;
        try {
            deptVO = persistenceRetrieve.retrieveByPk(DeptVO.class, pkDept, null);
            if (deptVO == null) {
                return null;
            }
            // 获取所选部门的innercode
            String innercode = (String) deptVO.getAttributeValue("innercode");
            String sql = "select org_dept.pk_dept from org_dept inner join org_admin_enable on org_dept.pk_org=org_admin_enable.pk_adminorg where org_dept.hrcanceled<>'Y' and org_dept.innercode like '" + innercode + "%'";
            List<String> deptIds = (List<String>) NCLocator.getInstance().lookup(IUAPQueryBS.class).executeQuery(sql,
                    new StringListProcessor());
            InSQLCreator isc = new InSQLCreator();
            if(deptMap.isEmpty()) {
                strInSql = isc.getInSQL(deptIds.toArray(new String[0]));
            } else {
                List<String> ids = new ArrayList<>();
                for (String deptId : deptIds) {
                    if (deptMap.containsKey(deptId)) {
                        ids.add(deptId);
                    }
                }
                strInSql = isc.getInSQL(ids.toArray(new String[0]));
            }
        } catch (BusinessException e) {
            Logger.error(e.getMessage(), e);
            throw new RuntimeException(ResHelper.getString("6020hrkq", "6020hrkq00039")
                    /*@res "查询下级部门异常！" */);
        }
        return strInSql;
    }
}
