import { IssueEnhancerInterface } from '@app/event-emitter/issue-enhancers/issue-enhancer-interface';
import { RedmineTypes } from '@app/event-emitter/models/redmine-types';
import { UsersService } from '@app/event-emitter/users/users.service';
import { Injectable } from '@nestjs/common';
@Injectable()
export class CustomFieldsEnhancer implements IssueEnhancerInterface {
  name = 'custom-fields';

  constructor(private usersService: UsersService) {}

  async enhance(
    issue: RedmineTypes.Issue,
  ): Promise<RedmineTypes.Issue & Record<string, any>> {
    const res: RedmineTypes.Issue & Record<string, any> = { ...issue };

    const customFields = issue.custom_fields;
    if (!customFields) {
      return issue;
    }

    const qa = customFields.find(
      (cf) => cf.name === 'Quality Assurance' || cf.name === 'QA',
    );
    if (qa && this.isNumber(qa.value)) {
      const qaUserId = Number(qa.value);
      const qaUser = await this.usersService.getUser(qaUserId);
      if (qaUser) {
        res.qa = { ...qaUser };
      }
    }

    const cr = customFields.find(
      (cf) => cf.name === 'Code Reviewer' || cf.name === 'CR',
    );
    if (cr && this.isNumber(cr.value)) {
      const crUserId = Number(cr.value);
      const crUser = await this.usersService.getUser(crUserId);
      if (crUser) {
        res.cr = { ...crUser };
      }
    }

    const dev = issue.assigned_to;
    if (dev && dev.id) {
      const devUser = await this.usersService.getUser(dev.id);
      if (devUser) {
        res.dev = { ...devUser };
      }
    }

    const tags = customFields.find((cf) => cf.name === 'Tags');
    if (tags && tags.value) {
      res.tags = tags.value
        .split(/[ ,;]/)
        .map((s) => s.trim())
        .filter((s) => !!s);
    }

    const sp = customFields.find(
      (cf) => cf.name === 'Story Points' || cf.name === 'SP',
    );
    if (sp && this.isNumber(sp.value)) {
      res.sp = Number(sp.value);
    }

    return res;
  }

  private isNumber(value): boolean {
    return !Number.isNaN(value) && Number.isFinite(Number(value));
  }
}
