import { Inject, Provide } from '@midwayjs/decorator';
import { BaseService } from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import * as _ from 'lodash';
import * as moment from 'moment';
import { MerchantEntity } from '../entity/merchant';
import { Utils } from '../../../comm/utils';
import { AgentEntity } from '../entity/agent';
import { AgentMerchantEntity } from '../entity/agentMerchant';

@Provide()
export class DashboardService extends BaseService {
  @InjectEntityModel(MerchantEntity)
  merchantEntity: Repository<MerchantEntity>;

  @InjectEntityModel(AgentEntity)
  agentEntity: Repository<AgentEntity>;

  @InjectEntityModel(AgentMerchantEntity)
  agentMerchantEntity: Repository<AgentMerchantEntity>;

  @Inject()
  ctx;

  @Inject()
  utils: Utils;

  async dashboard(query) {
    let { mchId = '' } = query;
    let mchIds = [];
    const { roleIds, userId } = this.ctx.admin;
    if (this.utils.isMerchant(roleIds)) {
      const merchant = await this.merchantEntity.findOneBy({ userId });
      if (merchant) {
        mchId = merchant.mchId;
      } else {
        mchId = '-1';
      }
    } else if (this.utils.isAgent(roleIds)) {
      const agent = await this.agentEntity.findOne({
        where: {
          userId: userId
        }
      })
      const agentMchs = await this.agentMerchantEntity.findBy({ agentId: agent.id + '' })
      mchIds = agentMchs.map(item => {
        return "'" + item.mchId + "'";
      })
      if (mchIds.length === 0) {
        mchIds = ["'-1'"]
      }
    }
    const todayTime = [
      moment().format('YYYY-MM-DD') + ' 00:00:00',
      moment().format('YYYY-MM-DD') + ' 23:59:59',
    ];
    const data = await Promise.all(
      [todayTime].map(item => {
        return this.nativeQuery(
          `SELECT 
        count(*) as num1,
        SUM(IF(a.status = 1, 1, 0)) as num2,
        SUM(IF(a.status = 1, a.amount, 0)) as num3
        FROM dj_order a WHERE 1=1
        ${this.utils.isMerchant(roleIds)
            ? this.setSql(mchId, 'and a.mchId = ?', [`${mchId}`])
            : this.setSql(mchId, 'and a.mchId like ?', [`%${mchId}%`])
          }
        ${mchIds.length > 0 ? `and a.mchId in (${mchIds.join(',')})` : ''}
        ${this.setSql(true, 'and (a.createTime between ? and ?)', item)}
      `
        );
      })
    );
    return data.map(item => {
      return item[0];
    });
  }

  async chartData(query) {
    let { mchId = '', date = [], dateType = '1d', type = '0' } = query;
    let mchIds = [];
    const { roleIds, userId } = this.ctx.admin;
    if (this.utils.isMerchant(roleIds)) {
      const merchant = await this.merchantEntity.findOneBy({ userId });
      if (merchant) {
        mchId = merchant.mchId;
      } else {
        mchId = '-1';
      }
    } else if (this.utils.isAgent(roleIds)) {
      const agent = await this.agentEntity.findOne({
        where: {
          userId: userId
        }
      })
      const agentMchs = await this.agentMerchantEntity.findBy({ agentId: agent.id + '' })
      mchIds = agentMchs.map(item => {
        return "'" + item.mchId + "'";
      })
      if (mchIds.length === 0) {
        mchIds = ["'-1'"]
      }
    }

    let sql = 'SELECT ';
    switch (dateType) {
      case '1m':
        sql += 'FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(createTime) / 60) * 60) AS time, '
        break;
      case '5m':
        sql += 'FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(createTime) / 300) * 300) AS time, '
        break;
      case '10m':
        sql += 'FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(createTime) / 300) * 300) AS time, '
        break;
      case '1h':
        sql += `DATE_FORMAT(createTime, '%Y-%m-%d %H:00:00') AS time, `
        break;
      default:
        sql += 'DATE(createTime) as time, '
        break;
    }
    switch (type) {
      case '1':
        sql += 'SUM(IF(status=1, 1, 0)) as num '
        break;
      case '2':
        sql += 'SUM(IF(status=1, amount, 0)) as num '
        break;
      case '3':
        sql += 'sum(1) as num, SUM(IF(status=1, 1, 0)) as num1 '
        break;
      default:
        sql += 'sum(1) as num '
        break;
    }

    sql += `FROM dj_order WHERE 1=1
    ${this.utils.isMerchant(roleIds)
        ? this.setSql(mchId, ' and mchId = ?', [`${mchId}`])
        : this.setSql(mchId, ' and mchId like ?', [`%${mchId}%`])
      }
      ${mchIds.length > 0 ? `and mchId in (${mchIds.join(',')})` : ''}
    ${this.setSql(
        date && date.length === 2,
        ' and (createTime between ? and ?)',
        date
      )}
     GROUP BY time ORDER BY time`
    return this.nativeQuery(sql);
  }
}
