'use strict';

async function appList (ctx) {
   try {
      const models = ctx.fs.dc.models;

      const appRes = await models.App.findAll({

      })
      ctx.status = 200;
      ctx.body = appRes
   } catch (error) {
      ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
      ctx.status = 400;
      ctx.body = {
         message: typeof error == 'string' ? error : undefined
      }
   }
}

async function pomsProject (ctx) {
   try {
      const models = ctx.fs.dc.models;
      const { clickHouse } = ctx.app.fs
      const { userId, pepUserId, userInfo, pepUserInfo } = ctx.fs.api
      const { limit, page, global, pepId, keyword } = ctx.query

      let findOption = {
         where: {
            del: false,
            // $or:[]
         },
         order: [['updateTime', 'desc']],
         distinct: true,
         include: {
            model: models.App,
         }
      }
      if (global && !userInfo.role.includes('SuperAdmin') && !userInfo.role.includes('admin')) {
         findOption.where.id = { $in: userInfo.correlationProject }
      }
      if (pepId) {
         findOption.where.id = pepId
      }
      if (limit) {
         findOption.limit = limit
      }
      if (page && limit) {
         findOption.offset = page * limit
      }
      if (keyword) {
         const project = await clickHouse.projectManage.query(
            `
            SELECT 
               t_pim_project.id AS id, 
               t_pim_project.project_name AS project_name, 
               t_pim_project.isdelete AS isdelete,
               t_pim_project_construction.construction_status_id AS construction_status_id, 
               t_pim_project_state.construction_status AS construction_status 
            FROM t_pim_project 
               LEFT JOIN t_pim_project_construction 
                  ON t_pim_project.id = t_pim_project_construction.project_id 
               LEFT JOIN t_pim_project_state 
                  ON t_pim_project_construction.construction_status_id = t_pim_project_state.id 
               WHERE project_name LIKE '%${keyword}%'
            `
         ).toPromise() || []
         
         const anxinProjectRes = await clickHouse.anxinyun.query(
            `SELECT id,"name",
              project_state AS projectState 
            FROM t_project 
              WHERE name LIKE '%${keyword}%'`).toPromise()
            || []
         let projectId = project.map(v => v.id)
         let anxinProjectId = anxinProjectRes.map(v => v.id)

         findOption.where.$or = [
            { name: { $like: `%${keyword}%` } } ]
         if (projectId.length > 0) {
            findOption.where.$or.push({ pepProjectId: { $in: projectId } })
         }
         if (anxinProjectId.length > 0) {
            findOption.where.$or.push({ anxinProjectId: { $overlap: anxinProjectId } })
         }

      }

      const proRes = await models.ProjectCorrelation.findAndCountAll(findOption)

      let pepProjectIds = new Set()
      let anxinProjectIds = new Set()
      let createUsers = new Set()
      for (let p of proRes.rows) {
         if (p.pepProjectId) {
            pepProjectIds.add(p.pepProjectId)
         }
         if (p.createUser) {
            createUsers.add(p.createUser)
         }
         for (let ap of p.anxinProjectId) {
            if (ap) {
               anxinProjectIds.add(ap)
            }
         }
      }
      const pomsUser = await models.User.findAll({
         where: {
            id: { $in: [...createUsers] }
         }
      })
      let pepUserIds = new Set()
      for (let p of pomsUser) {
         if (p.pepUserId) {
            pepUserIds.add(p.pepUserId)
         }
      }
      const pepcaUser = pepUserIds.size ?
         await clickHouse.pepEmis.query(
            `
            SELECT * FROM user
               WHERE id IN (${[...pepUserIds].join(',')}, -1)
            `
         ).toPromise() :
         []

      const pepProjectRes = pepProjectIds.size ?
         await clickHouse.projectManage.query(
            `
            SELECT 
               t_pim_project.id AS id, 
               t_pim_project.project_name AS project_name, 
               t_pim_project.isdelete AS isdelete,
               t_pim_project_construction.construction_status_id AS construction_status_id, 
               t_pim_project_state.construction_status AS construction_status 
            FROM t_pim_project 
               LEFT JOIN t_pim_project_construction 
                  ON t_pim_project.id = t_pim_project_construction.project_id 
               LEFT JOIN t_pim_project_state 
                  ON t_pim_project_construction.construction_status_id = t_pim_project_state.id 
               WHERE id IN (${[...pepProjectIds].join(',')}, -1)
            `
         ).toPromise() :
         []


      const anxinProjectRes = anxinProjectIds.size ?
         await clickHouse.anxinyun.query(`SELECT id,"name",project_state AS projectState FROM t_project WHERE id IN (${[...anxinProjectIds].join(',')},-1)`).toPromise() :
         []


      for (let p of proRes.rows) {
         const corPro = pepProjectRes.find(pp => pp.id == p.pepProjectId) || {}
         const pepUserName = (pepcaUser.find(qq => qq.id == (pomsUser.find(oo => oo.id == p.createUser) || {}).pepUserId) || {}).name || ''
         p.dataValues.pepProjectName = corPro.project_name
         p.dataValues.pepProjectIsDelete = corPro.isdelete
         p.dataValues.constructionStatusId = corPro.construction_status_id
         p.dataValues.constructionStatus = corPro.construction_status

         let nextAnxinProject = anxinProjectRes.filter(ap => p.anxinProjectId.includes(ap.id))
         p.dataValues.anxinProject = nextAnxinProject
         p.dataValues.pepUserName = pepUserName
         delete p.dataValues.anxinProjectId
      }
      ctx.status = 200;
      ctx.body = proRes
   } catch (error) {
      ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`)
      ctx.status = 400;
      ctx.body = {
         message: typeof error == 'string' ? error : undefined
      }
   }
}

async function projectAnxincloud (ctx) {
   try {
      const { clickHouse } = ctx.app.fs
      const { includeDelete } = ctx.query

      const projectRes = await clickHouse.anxinyun.query(`SELECT * FROM t_project WHERE project_state = 4 ${includeDelete == 1 ? 'OR project_state = -1' : ''} ORDER BY id DESC`).toPromise()

      ctx.status = 200;
      ctx.body = projectRes
   } catch (error) {
      ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
      ctx.status = 400;
      ctx.body = {
         message: typeof error == 'string' ? error : undefined
      }
   }
}

async function projectPManage (ctx) {
   try {
      const models = ctx.fs.dc.models;
      const { clickHouse } = ctx.app.fs
      const { includeDelete } = ctx.query

      const projectRes = await clickHouse.projectManage.query(`SELECT id, project_name, isdelete FROM t_pim_project WHERE isdelete=0 ${includeDelete == 1 ? 'OR isdelete=1' : ''} ORDER BY id DESC`).toPromise()

      const bindedPRes = await models.ProjectCorrelation.findAll({
         where: {
            pepProjectId: { $ne: null },
            del: false
         }
      })

      for (let p of projectRes) {
         if (bindedPRes.some(bp => bp.pepProjectId == p.id)) {
            p.binded = true
         }
      }

      ctx.status = 200;
      ctx.body = projectRes
   } catch (error) {
      ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
      ctx.status = 400;
      ctx.body = {
         message: typeof error == 'string' ? error : undefined
      }
   }
}

async function pepProjectConstrictionState (ctx) {
   try {
      const { models } = ctx.fs.dc;
      const { clickHouse } = ctx.app.fs

      const cRes = await clickHouse.projectManage.query(`
         SELECT * FROM t_pim_project_state ORDER BY id
      `).toPromise()

      ctx.status = 200;
      ctx.body = cRes
   } catch (error) {
      ctx.fs.logger.error(`path: ${ctx.path}, error: error`);
      ctx.status = 400;
      ctx.body = {
         message: typeof error == 'string' ? error : undefined
      }
   }
}

async function strucWithPomsProject (ctx) {
   try {
      const { models } = ctx.fs.dc;
      const { clickHouse } = ctx.app.fs
      const { pomsProjectId } = ctx.query

      const bindRes = await models.ProjectCorrelation.findAll({
         where: {
            id: { $in: pomsProjectId.split(',') }
         }
      })
      let anxinProjectIds = new Set()
      for (let b of bindRes) {
         if (b.anxinProjectId.length) {
            for (let aid of b.anxinProjectId) {
               anxinProjectIds.add(aid)
            }
         }
      }

      let undelStruc = []
      if (bindRes) {
         const undelStrucRes = anxinProjectIds.size ?
            await clickHouse.anxinyun.query(
               `  
               SELECT 
                  t_structure.id AS strucId, 
                  t_structure.name AS strucName,
                  t_factor.id AS factorId, 
                  t_factor.name AS factorName,
                  t_factor.proto AS factorProto,
                  t_factor_proto_item.name AS factorItemName,
                  t_factor_proto_item.id AS factorItemId
               FROM 
                  t_project 
               LEFT JOIN
                  t_project_structure
                     ON t_project_structure.project = t_project.id
               LEFT JOIN
                  t_project_structuregroup
                     ON t_project_structuregroup.project = t_project.id
               LEFT JOIN 
                  t_structuregroup_structure
                     ON t_structuregroup_structure.structuregroup = t_project_structuregroup.structuregroup
               LEFT JOIN
                  t_project_construction
                     ON t_project_construction.project = t_project.id
               LEFT JOIN
                  t_structure_site
                     ON t_structure_site.siteid = t_project_construction.construction
               RIGHT JOIN
                  t_structure
                     ON t_structure.id = t_project_structure.structure
                     OR t_structure.id = t_structuregroup_structure.structure
                     OR t_structure.id = t_structure_site.structid
               LEFT JOIN t_structure_factor
                     ON t_structure_factor.structure = t_structure.id
               LEFT JOIN t_factor
                     ON t_structure_factor.factor = t_factor.id
               LEFT JOIN t_factor_proto_item
                     ON t_factor_proto_item.proto = t_factor.proto
               WHERE 
                  project_state != -1 
                     AND
                  t_project.id IN (${[...anxinProjectIds].join(',')}, -1)
               ORDER BY strucId
            `
            ).toPromise() :
            []
         for (let s of undelStrucRes) {
            let corStrut = undelStruc.find(us => us.id == s.strucId)
            if (!corStrut) {
               let nextFacor = []
               if (s.factorId) {
                  let nextFactorItem = []
                  if (s.factorItemId) {
                     nextFactorItem.push({
                        id: s.factorItemId,
                        name: s.factorItemName,
                     })
                  }
                  nextFacor.push({
                     id: s.factorId,
                     name: s.factorName,
                     proto: s.factorProto,
                     item: nextFactorItem,
                  })
               }
               undelStruc.push({
                  id: s.strucId,
                  name: s.strucName,
                  factor: nextFacor
               })
            } else {
               if (s.factorId) {
                  let corFactor = corStrut.factor.find(v => v.id == s.factorId)
                  let nextFactorItem = null
                  if (s.factorItemId) {
                     nextFactorItem = {
                        id: s.factorItemId,
                        name: s.factorItemName,
                     }
                  }
                  if (corFactor) {
                     if (!corFactor.item.some(fi => fi.id == s.factorItemId) && nextFactorItem) {
                        corFactor.item.push(nextFactorItem)
                     }
                  } else {
                     corStrut.factor.push({
                        id: s.factorId,
                        name: s.factorName,
                        proto: s.factorProto,
                        item: nextFactorItem ? [{
                           id: s.factorItemId,
                           name: s.factorItemName,
                        }] : [],
                     })
                  }
               }
            }
         }
      }

      ctx.status = 200;
      ctx.body = undelStruc
   } catch (error) {
      ctx.fs.logger.error(`path: ${ctx.path}, error: error`);
      ctx.status = 400;
      ctx.body = {
         message: typeof error == 'string' ? error : undefined
      }
   }
}

module.exports = {
   appList,
   projectAnxincloud,
   projectPManage,
   pomsProject,
   pepProjectConstrictionState,
   strucWithPomsProject,
};