'use strict';
const moment = require('moment')
const request = require('superagent');

module.exports = function (app, opts) {

   async function memberList ({
      keywordTarget, keyword, limit, page, state,
      hiredateStart, hiredateEnd, marital, native, workPlace,
      orderBy, orderDirection,
      nowAttendanceTime,
      overtimeDayStatisticStartDate, overtimeDayStatisticendDate,
      overtimeCountStatistic, overtimeCountStatisticStartDate, overtimeCountStatisticendDate,
      vacateDayStatisticStartDate, vacateDayStatisticendDate,
      vacateDurationStatistic, vacateCountStatistic, vacateCountStatisticStartDate, vacateCountStatisticendDate
   }) {
      const { judgeHoliday } = app.fs.utils
      const { clickHouse } = app.fs
      const { database: pepEmis } = clickHouse.pepEmis.opts.config

      const curDay = moment().format('YYYY-MM-DD')
      const nowTime = moment()
      let whereOption = []
      let whereFromSelectOption = []
      let returnEmpty = false
      if (state == 'inOffice') {
         // 在岗
         const holidayJudge = await judgeHoliday(curDay)
         if (holidayJudge) {
            if (
               holidayJudge.workday
               && nowTime.isAfter(moment(curDay + ' 08:30'))
               && nowTime.isBefore(moment(curDay + ' 17:30'))
            ) {
               // 在工作日的工作时间范围 无请假记录
               whereFromSelectOption.push(`vacateStartTime = '1970-01-01 00:00:00.000000'`)
            } else {
               returnEmpty = true
            }
         } else {
            returnEmpty = true
         }
      }
      if (state == 'dayoff') {
         // 放假
         const holidayJudge = await judgeHoliday(curDay)
         if (holidayJudge) {
            if (
               holidayJudge.dayoff || holidayJudge.festivals
            ) {
               // 在休息日范围内且无加班申请
               whereFromSelectOption.push(`overtimeStartTime = '1970-01-01 00:00:00.000000'`)
            } else {
               returnEmpty = true
            }
         } else {
            returnEmpty = true
         }
      }
      if (returnEmpty) {
         return {
            count: 0,
            rows: []
         }
      }

      let overtimeDayStatisticWhere = []
      if (overtimeDayStatisticStartDate) {
         overtimeDayStatisticWhere.push(`overtime_day.day >= '${moment(overtimeDayStatisticStartDate).format('YYYY-MM-DD')}'`)
      }
      if (overtimeDayStatisticendDate) {
         overtimeDayStatisticWhere.push(`overtime_day.day <= '${moment(overtimeDayStatisticendDate).format('YYYY-MM-DD')}'`)
      }

      let overtimeCountStatisticWhere = []
      if (overtimeCountStatisticStartDate) {
         overtimeCountStatisticWhere.push(`overtime.start_time >= '${moment(overtimeCountStatisticStartDate).startOf('day').format('YYYY-MM-DD HH:mm:ss')}'`)
      }
      if (overtimeCountStatisticendDate) {
         overtimeCountStatisticWhere.push(`overtime.end_time <= '${moment(overtimeCountStatisticendDate).endOf('day').format('YYYY-MM-DD HH:mm:ss')}'`)
      }

      let vacateDayStatisticWhere = []
      if (vacateDayStatisticStartDate) {
         vacateDayStatisticWhere.push(`vacate_day.day >= '${moment(vacateDayStatisticStartDate).format('YYYY-MM-DD')}'`)
      }
      if (vacateDayStatisticendDate) {
         vacateDayStatisticWhere.push(`vacate_day.day <= '${moment(vacateDayStatisticendDate).format('YYYY-MM-DD')}'`)
      }

      let vacateCountStatisticWhere = []
      if (vacateCountStatisticStartDate) {
         vacateCountStatisticWhere.push(`vacate.start_time >= '${moment(vacateCountStatisticStartDate).startOf('day').format('YYYY-MM-DD HH:mm:ss')}'`)
      }
      if (vacateCountStatisticendDate) {
         vacateCountStatisticWhere.push(`vacate.end_time <= '${moment(vacateCountStatisticendDate).endOf('day').format('YYYY-MM-DD HH:mm:ss')}'`)
      }
      // CRAZY
      const innerSelectQuery = `
         FROM member
         INNER JOIN ${pepEmis}.user AS user
            ON member.pep_user_id = user.id
            ${keywordTarget == 'number' && keyword ? `
               AND user.people_code LIKE '%${keyword}%'
            `: ''}
            ${keywordTarget == 'name' && keyword ? `
               AND user.name LIKE '%${keyword}%'
            `: ''}

         ${nowAttendanceTime ? `
            ${state == 'vacate' ? 'INNER' : 'LEFT'} JOIN (
               SELECT
                  pep_user_id,
                  any(start_time) AS vacateStartTime,
                  any(end_time) AS vacateEndTime
               FROM vacate
               WHERE
                  start_time <= '${nowTime.format('YYYY-MM-DD HH:mm:ss')}'
                  AND end_time > '${nowTime.format('YYYY-MM-DD HH:mm:ss')}'
               GROUP BY pep_user_id
            ) AS hrVacate
               ON hrVacate.pep_user_id = member.pep_user_id
            `: ''}
         ${nowAttendanceTime ? `
            LEFT JOIN (
               SELECT 
                  pep_user_id, 
                  any(start_time) AS overtimeStartTime,
                  any(end_time) AS overtimeEndTime
               FROM overtime
               WHERE
                  start_time <= '${nowTime.format('YYYY-MM-DD HH:mm:ss')}'
                  AND end_time > '${nowTime.format('YYYY-MM-DD HH:mm:ss')}'
               GROUP BY pep_user_id
            ) AS hrOvertime
               ON hrOvertime.pep_user_id = member.pep_user_id  
         `: ''}

         ${orderBy == 'overtimeTakeRestSum' ||
            orderBy == 'overtimePaySum' ||
            orderBy == 'overtimeSum' ?
            `LEFT JOIN (
               SELECT
                  overtime.pep_user_id AS pepUserId,
                  sum(overtime_day.duration) AS duration
               FROM overtime_day
                  INNER JOIN overtime
                     ON overtime.id = overtime_day.overtime_id
                     ${orderBy == 'overtimeTakeRestSum' ? `AND overtime.compensate = '调休'` : ''}
                     ${orderBy == 'overtimePaySum' ? `AND overtime.compensate = '发放加班补偿'` : ''}
               ${overtimeDayStatisticWhere.length ? `
                  WHERE ${overtimeDayStatisticWhere.join(' AND ')}
               `: ''}
               GROUP BY overtime.pep_user_id
            ) AS overtimeDayStatistic
               ON overtimeDayStatistic.pepUserId = member.pep_user_id`: ''}
            
         ${overtimeCountStatistic ? `
            LEFT JOIN (
               SELECT
                  overtime.pep_user_id AS pepUserId,
                  count(pep_process_story_id) AS count
               FROM overtime
               ${overtimeCountStatisticWhere.length ? `
                  WHERE ${overtimeCountStatisticWhere.join(' AND ')}
               `: ''}
               GROUP BY overtime.pep_user_id
            ) AS overtimeCountStatistic
            ON overtimeCountStatistic.pepUserId = member.pep_user_id
         `: ''}

         ${vacateDurationStatistic ||
            orderBy == 'vacateSum' ?
            `LEFT JOIN (
               SELECT
                  vacate.pep_user_id AS pepUserId,
                  sum(vacate_day.duration) AS duration
               FROM vacate_day
                  INNER JOIN vacate
                     ON vacate.id = vacate_day.vacate_id
               ${vacateDayStatisticWhere.length ? `
                  WHERE ${vacateDayStatisticWhere.join(' AND ')}
               `: ''}
               GROUP BY vacate.pep_user_id
            ) AS vacateDayStatistic
               ON vacateDayStatistic.pepUserId = member.pep_user_id`: ''}
            
         ${vacateCountStatistic ? `
            LEFT JOIN (
               SELECT
                  vacate.pep_user_id AS pepUserId,
                  count(pep_process_story_id) AS count
               FROM vacate
               ${vacateCountStatisticWhere.length ? `
                  WHERE ${vacateCountStatisticWhere.join(' AND ')}
               `: ''}
               GROUP BY vacate.pep_user_id
            ) AS vacateCountStatistic
            ON vacateCountStatistic.pepUserId = member.pep_user_id
         `: ''}
         WHERE
            member.del = '0'
            ${keywordTarget == 'post' && keyword ? `
               AND user.post IN (
                  SELECT basicDataPost.id
                  FROM ${pepEmis}.basicdata_post AS basicDataPost
                  where basicDataPost.name LIKE '%${keyword}%'
               )
            ` : ''}
            ${keywordTarget == 'dep' && keyword ? `
               AND user.id IN (
                  SELECT department_user.user
                  FROM ${pepEmis}.department_user AS department_user
                  INNER JOIN ${pepEmis}.department AS department
                     ON department.id = department_user.department
                     AND department.name LIKE '%${keyword}%'
               )
            ` : ''}
            ${state == 'dimission' ? `AND member.dimission_date IS NOT null` : ''}
            ${state == 'onJob' ? `AND member.dimission_date IS null` : ''}
            ${whereFromSelectOption.length && nowAttendanceTime ? `AND ${whereFromSelectOption.join('AND')}` : ''}
            ${hiredateStart ? `
               AND member.hiredate >= '${moment(hiredateStart).format('YYYY-MM-DD')}'
            `: ''}
            ${hiredateEnd ? ` 
               AND member.hiredate <= '${moment(hiredateEnd).format('YYYY-MM-DD')}'
            ` : ''}
            ${marital ? `
               AND member.marital = '${marital}'
            `: ''}
            ${native ? `
               AND member.native_place = '${native}'
            `: ''}
            ${workPlace ? `
               AND member.work_place = '${workPlace}'
            `: ''}
      `

      const userRes = await clickHouse.hr.query(`
         SELECT 
            hrMember."member.pep_user_id" AS pepUserId,
            hrMember.*,
            user.name AS userName,
            user.people_code AS userCode,
            basicDataPost.name AS userPost,
            role.name AS roleName,
            role.id AS roleId,
            department.name AS depName,
            department.id AS depId,
            user.job AS userJob,
            user.active_status AS userActiveStatus,
            user.organization AS userOrganization
         FROM (
            SELECT 
               ${orderBy == 'overtimeTakeRestSum'
            || orderBy == 'overtimePaySum'
            || orderBy == 'overtimeSum' ? `
                  overtimeDayStatistic.duration AS overtimeDayStatisticDuration,
               `: ''}

               ${overtimeCountStatistic ? `
                  overtimeCountStatistic.count AS overtimeCount,
               `: ''}

               ${orderBy == 'vacateSum' || vacateDurationStatistic ? `
                  vacateDayStatistic.duration AS vacateDayStatisticDuration,
               `: ''}

               ${vacateCountStatistic ? `
                  vacateCountStatistic.count AS vacateCount,
               `: ''}
               
               ${nowAttendanceTime ? `
                  hrVacate.vacateStartTime AS vacateStartTime,
                  hrVacate.vacateEndTime AS vacateEndTime,
                  hrOvertime.overtimeStartTime AS overtimeStartTime,
                  hrOvertime.overtimeEndTime AS overtimeEndTime,
               `: ''}

               member.*
            ${innerSelectQuery}
            ${limit ? `LIMIT ${limit}` : ''}
            ${limit && page ? 'OFFSET ' + parseInt(limit) * parseInt(page) : ''}
         ) AS hrMember

            LEFT JOIN ${pepEmis}.user AS user
               ON pepUserId = user.id
            LEFT JOIN ${pepEmis}.user_role AS user_role
               ON ${pepEmis}.user_role.user = user.id
            LEFT JOIN ${pepEmis}.role AS role
               ON ${pepEmis}.role.id = user_role.role
            LEFT JOIN ${pepEmis}.basicdata_post AS basicDataPost
               ON ${pepEmis}.basicdata_post.id = user.post
            LEFT JOIN ${pepEmis}.department_user AS department_user
               ON department_user.user = user.id
            LEFT JOIN ${pepEmis}.department AS department
               ON department.id = department_user.department
            ${whereOption.length ? `WHERE ${whereOption.join(' AND ')}` : ''}
         ORDER BY ${orderBy == 'code' ?
            'user.people_code'
            : orderBy == 'hiredate'
               ? 'hrMember."member.hiredate"'
               : orderBy == 'age'
                  ? 'hrMember."member.birthday"'
                  : orderBy == 'overtimeTakeRestSum'
                     || orderBy == 'overtimePaySum'
                     || orderBy == 'overtimeSum' ?
                     'hrMember.overtimeDayStatisticDuration'
                     : orderBy == 'overtimeCount' ?
                        'hrMember.overtimeCount'
                        : orderBy == 'vacateSum' ?
                           'hrMember.vacateDayStatisticDuration'
                           : orderBy == 'vacateCount' ?
                              'hrMember.vacateCount'
                              : 'user.people_code'}
                  ${orderDirection || 'ASC'}
      `).toPromise()

      const countRes = await clickHouse.hr.query(`
         SELECT
         count(member.pep_user_id) AS count
            ${innerSelectQuery}
      `).toPromise()

      return {
         count: countRes[0].count,
         rows: userRes
      }
   }

   async function packageUserData (userRes, option = {}) {

      const { judgeHoliday, } = app.fs.utils
      let workTime = false
      let dayoffTime = false
      if (option.state) {
         const curDay = moment().format('YYYY-MM-DD')
         const nowTime = moment()
         const holidayJudge = await judgeHoliday(curDay)
         if (holidayJudge) {
            if (
               holidayJudge.workday
               && nowTime.isAfter(moment(curDay + ' 08:30'))
               && nowTime.isBefore(moment(curDay + ' 17:30'))
            ) {
               workTime = true
            } else if (holidayJudge.dayoff || holidayJudge.festivals) {
               dayoffTime = true
            }
         }
      }

      let returnD = []
      let pepUserIds = [-1]
      userRes.rows.forEach(u => {
         let existUser = returnD.find(r => r.pepUserId == u.pepUserId)
         if (existUser) {
            if (u.depId && !existUser.departmrnt.some(d => d.id == u.depId)) {
               existUser.departmrnt.push({
                  id: u.depId,
                  name: u.depName
               })
            }
            if (u.roleId && !existUser.role.some(r => r.id == u.roleId)) {
               existUser.role.push({
                  id: u.roleId,
                  name: u.roleName
               })
            }
         } else {
            let obj = {}
            for (let k in u) {
               let nextKey = k.replace('hrMember.', '')
                  .replace('member.', '')
               if (nextKey.includes('_')) {
                  nextKey = nextKey.toLowerCase()
                     .replace(
                        /(_)[a-z]/g,
                        (L) => L.toUpperCase()
                     )
                     .replace(/_/g, '')
               }
               obj[nextKey] = u[k] == '1970-01-01 00:00:00.000000' || u[k] == '1970-01-01 08:00:00.000000' ? null : u[k]
            }
            pepUserIds.push(u.pepUserId)
            console.log("查询到的用户信息:", obj);
            returnD.push({
               ...obj,
               departmrnt: u.depId ? [{
                  id: u.depId,
                  name: u.depName
               }] : [],
               role: u.roleId ? [{
                  id: u.roleId,
                  name: u.roleName
               }] : [],
               state: option.state ?
                  obj['dimissionDate'] ? 'dimission' :
                     obj['vacateStartTime'] ? 'vacate' :
                        workTime ? 'inOffice' :
                           dayoffTime ? 'dayoff' : 'rest'
                  : undefined,
               del: undefined,
               pepuserid: undefined
            })
         }
      })
      return { packageUser: returnD, pepUserIds }
   }

   return {
      memberList,
      packageUserData
   }
}