import { Provide } from '@midwayjs/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import { ContactApply } from '../../entity/users/contactApply.entity';
import { BaseServiceV2 } from '../../frame/BaseServiceV2';
import { get } from 'lodash';
import { Demand } from '../../entity/platform/demand.entity';
import { Supply } from '../../entity/platform/supply.entity';
import { Expert } from '../../entity/users/expert.entity';
import { User } from '../../entity/system/user.entity';
import { ErrorCode, ServiceError } from '../../error/service.error';
import { MessageUserType } from '../../public/var';

@Provide()
export class ContactApplyService extends BaseServiceV2 {
  getQueryColumnsOpera(): object {
    return {};
  }
  @InjectEntityModel(ContactApply)
  model: Repository<ContactApply>;

  @InjectEntityModel(Demand)
  demand: Repository<Demand>;

  @InjectEntityModel(Supply)
  supply: Repository<Supply>;

  @InjectEntityModel(Expert)
  expert: Repository<Expert>;

  @InjectEntityModel(User)
  user: Repository<User>;

  /**
   * 发送mq消息
   * 如果status是0,那就给被申请人发送;如果是1,那就给申请人发送联系方式,如果是-1:那就给申请人发送拒绝申请
   * 需求是先从需求中找联系方式,没有再从用户中招,其余的都直接从用户中找
   * @param id 数据id
   */
  async sendMqMsg(id) {
    const data = await this.model.createQueryBuilder().where(`"id" = :id`, { id }).getOne();
    if (!data) return;
    const status = get(data, 'status');
    const source = get(data, 'source');
    const source_id = get(data, 'source_id');
    const otherData = await this.searchCompleteData(source, source_id);
    const targetUserData = await this.getUserData(get(data, 'target_user'));
    const applyUserData = await this.getUserData(get(data, 'apply_user'));
    let sourceStr;
    let sourceProp;
    let sourcePropValue;
    let mqTarget;
    let msgStr;
    let mqUserType = MessageUserType.USER;
    let mqUserNickName;
    switch (source) {
      case 'demand':
        sourceStr = '需求';
        sourceProp = 'name';
        break;
      case 'supply':
        sourceStr = '供给';
        sourceProp = 'name';
        break;
      case 'expert':
        sourceStr = '专家';
        break;
      default:
        break;
    }
    const sourceData = get(otherData, 'sourceData');
    if (sourceProp) sourcePropValue = get(sourceData, sourceProp);
    switch (status) {
      case '0':
        // 给被申请人发送和mq消息
        mqTarget = get(data, 'target_user');
        mqUserNickName = get(targetUserData, 'nick_name');
        const apply_userName = get(applyUserData, 'nick_name');
        msgStr = `用户${apply_userName} 通过 ${sourceStr}数据 ${sourcePropValue ? `- ${sourcePropValue}` : ''} 申请获取您的联系方式,尽快审核避免错失良机!`;
        break;
      case '1':
        // 给申请人发送消息和mq消息
        mqTarget = get(data, 'apply_user');
        mqUserNickName = get(applyUserData, 'nick_name');
        const contacts = this.getContactObject(otherData, source);
        msgStr = `您通过 ${sourceStr}数据 ${sourcePropValue ? `- ${sourcePropValue}` : ''} 获取对方联系方式的申请已通过.`;
        // 拼接联系方式
        const person = get(contacts, 'person');
        if (person) msgStr = `${msgStr} 联系人: ${person};`;
        const phone = get(contacts, 'phone');
        if (phone) msgStr = `${msgStr} 联系电话: ${phone};`;
        const email = get(contacts, 'email');
        if (email) msgStr = `${msgStr} 邮箱: ${email}`;
        break;
      case '-1':
        mqTarget = get(data, 'apply_user');
        mqUserNickName = get(applyUserData, 'nick_name');
        msgStr = `您通过 ${sourceStr}数据 ${sourcePropValue ? `- ${sourcePropValue}` : ''} 获取对方联系方式的申请已被拒绝.`;
        break;
      default:
        break;
    }
    // 创建消息,发送
    const to = [{ user: mqTarget, user_type: mqUserType, user_nick_name: mqUserNickName }];
    const msgObj = { content: msgStr, to, type: '0' };
    return msgObj;
  }
  /**
   * 获取用户数据
   * @param id 用户id
   * @returns
   */
  async getUserData(id) {
    const user = await this.user.createQueryBuilder().where(`"id" = :id`, { id }).getOne();
    return user;
  }
  /**
   * 根据 apply_user ,target_user检查是否有过申请且已通过审核的数据
   * 如果有:直接返回信息;
   * 如果没有,返回继续执行
   * @param data
   */
  async checkHasApply(data) {
    const apply_user = get(data, 'apply_user');
    const target_user = get(data, 'target_user');
    const builder = this.model.createQueryBuilder().where(`"apply_user" = :apply_user`, { apply_user }).andWhere(`"target_user" = :target_user`, { target_user });
    const apply = await builder.andWhere(`"status" = :status`, { status: '1' }).getOne();
    if (apply) {
      const msgObj = await this.sendMqMsg(get(apply, 'id'));
      return { status: '1', content: msgObj.content };
    }
    // 查询是不是有其他状态的申请: 未审核,已拒绝,如果有,就根据状态返回提示语
    const othersApply = await builder.getOne();
    // 没有找到其他的申请,直接返回
    if (!othersApply) return;
    const status = get(othersApply, 'status');
    // 有没审核的申请,抛出异常
    if (status === '0') throw new ServiceError(ErrorCode.CONTACTAPPLY_HAS_APPLY_NOT_STATUS);
    // 被拒绝了也允许重新申请
    else if (status === '-1') return;
  }
  /**
   * 组织联系信息
   * @param data searchCompleteData的返回
   * @param source 来源
   */
  getContactObject(data, source) {
    const contacts: any = {};
    if (source === 'demand') {
      const sourceData = get(data, 'sourceData');
      contacts.phone = get(sourceData, 'tel');
      contacts.person = get(sourceData, 'contacts');
    }
    if (Object.keys(contacts).length <= 0) {
      const user = get(data, 'userData');
      contacts.phone = get(user, 'phone');
      contacts.person = get(user, 'nick_name');
      contacts.email = get(user, 'email');
    }
    return contacts;
  }

  /**
   * 根据source和source_id,查找数据,再查找数据拥有人的信息,返回数据
   * @param source 数据来源
   * @param source_id 数据来源的id
   */
  async searchCompleteData(source, source_id) {
    let model = this[source];
    if (!model) return;
    const sourceData = await model.createQueryBuilder().where(`"id" = :id`, { id: source_id }).getOne();
    if (!sourceData) return;
    const result = { sourceData };
    const userId = get(sourceData, 'user');
    if (!userId) return result;
    const user = await this.user.createQueryBuilder().where(`"id" = :id`, { id: userId }).getOne();
    if (!user) return result;
    result['userData'] = user;
    return result;
  }
}
