/* eslint-disable @typescript-eslint/no-namespace */
import { Injectable, Logger } from '@nestjs/common';
import { RedmineTypes } from '../models/redmine-types';
import { IssueEnhancerInterface } from './issue-enhancer-interface';

export namespace TagStyledEnhancerNs {
  /**
   * * key - tag name,
   * * value - css style for tag
   */
  export type Styles = Record<string, string>;

  export type StyledTag = {
    tag: string;
    style: string;
  };

  export type TagsParams = {
    tagsKeyName: string;
    styles: Styles;
    defaultStyle: string;
    styledTagsKeyName: string;
  };

  export type ConfigWithTagsStyles = {
    tags?: TagsParams;
    [key: string]: any;
  };

  export function CreateTagStyledEnhancerForConfig(
    cfg: ConfigWithTagsStyles,
  ): TagStyledEnhancer | null {
    if (!cfg || !cfg.tags) return null;
    return new TagStyledEnhancer(
      (issue: RedmineTypes.ExtendedIssue) => {
        if (!issue) return [];
        if (
          typeof issue[cfg.tags.tagsKeyName] === 'object' &&
          issue[cfg.tags.tagsKeyName].length > 0
        ) {
          return issue[cfg.tags.tagsKeyName];
        } else {
          return [];
        }
      },
      cfg.tags.styles,
      cfg.tags.defaultStyle,
      cfg.tags.styledTagsKeyName,
    );
  }
}

export class TagStyledEnhancer implements IssueEnhancerInterface {
  name = 'tag-styled';

  constructor(
    private tagsGetter: (issue: RedmineTypes.ExtendedIssue) => string[],
    private styles: TagStyledEnhancerNs.Styles,
    private defaultStyle: string,
    private keyName: string,
  ) {}

  async enhance(
    issue: RedmineTypes.ExtendedIssue,
  ): Promise<RedmineTypes.ExtendedIssue> {
    if (!issue) return issue;
    const tags = this.tagsGetter(issue);
    const styles = [] as TagStyledEnhancerNs.StyledTag[];
    for (let i = 0; i < tags.length; i++) {
      const tagName = tags[i];
      if (this.styles[tagName]) {
        styles.push({
          tag: tagName,
          style: this.styles[tagName],
        });
      } else {
        styles.push({
          tag: tagName,
          style: this.defaultStyle,
        });
      }
    }
    issue[this.keyName] = styles;
    return issue;
  }
}
