import { DynamicLoader } from '@app/event-emitter/configs/dynamic-loader';
import { RedmineEventsGateway } from '@app/event-emitter/events/redmine-events.gateway';
import { IssuesService } from '@app/event-emitter/issues/issues.service';
import { Controller, Get, Logger, Param, Render } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { parse } from 'jsonc-parser';
import { IssuesByTagsWidgetDataLoaderService } from './widget-data-loader/issues-by-tags.widget-data-loader.service';
import { RootIssueSubTreesWidgetDataLoaderService } from '@app/event-emitter/dashboards/widget-data-loader/root-issue-subtrees.widget-data-loader.service';
import { ListIssuesByUsersWidgetDataLoaderService } from '@app/event-emitter/dashboards/widget-data-loader/list-issues-by-users.widget-data-loader.service';
import { ListIssuesByUsersLikeJiraWidgetDataLoaderService } from '@app/event-emitter/dashboards/widget-data-loader/list-issues-by-users-like-jira.widget-data-loader.service';
import { ListIssuesByFieldsWidgetDataLoaderService } from '@app/event-emitter/dashboards/widget-data-loader/list-issues-by-fields.widget-data-loader.service';

@Controller('simple-kanban-board')
export class SimpleKanbanBoardController {
  private logger = new Logger(SimpleKanbanBoardController.name);
  private path: string;

  constructor(
    private rootIssueSubTreesWidgetDataLoaderService: RootIssueSubTreesWidgetDataLoaderService,
    private dynamicLoader: DynamicLoader,
    private configService: ConfigService,
    private listIssuesByUsersWidgetDataLoaderService: ListIssuesByUsersWidgetDataLoaderService,
    private listIssuesByUsersLikeJiraWidgetDataLoaderService: ListIssuesByUsersLikeJiraWidgetDataLoaderService,
    private issuesByTagsWidgetDataLoaderService: IssuesByTagsWidgetDataLoaderService,
    private redmineEventsGateway: RedmineEventsGateway,
    private listIssuesByFieldsWidgetDataLoaderService: ListIssuesByFieldsWidgetDataLoaderService,
    private issuesService: IssuesService,
  ) {
    this.path = this.configService.get<string>('simpleKanbanBoard.path');
  }

  @Get('/tree/:name/raw')
  async getRawData(@Param('name') name: string): Promise<any> {
    const cfg = this.dynamicLoader.load(name, {
      path: this.path,
      ext: 'jsonc',
      parser: parse,
    });
    return await this.rootIssueSubTreesWidgetDataLoaderService.load(cfg);
  }

  @Get('/tree/:name')
  @Render('simple-kanban-board')
  async get(@Param('name') name: string): Promise<any> {
    return await this.getRawData(name);
  }

  @Get('/tree/:name/refresh')
  async refreshTree(@Param('name') name: string): Promise<any> {
    const cfg = this.dynamicLoader.load(name, {
      path: this.path,
      ext: 'jsonc',
      parser: parse,
    });
    const rootIssue = await this.issuesService.getIssueFromCache(
      cfg.rootIssueId,
    );
    const issues = await this.issuesService.getIssuesWithChildren(rootIssue);
    const issuesIds = issues.map((i) => i.id);
    this.logger.debug(`Issues for tree refresh - ${issuesIds}`);
    this.redmineEventsGateway.addIssues(issuesIds);
    return { success: true };
  }

  @Get('/by-users/:name/raw')
  async getByUsersRawData(@Param('name') name: string): Promise<any> {
    const cfg = this.dynamicLoader.load(name, {
      path: this.path,
      ext: 'jsonc',
      parser: parse,
    });
    return await this.listIssuesByUsersWidgetDataLoaderService.load(cfg);
  }

  @Get('/by-users/:name')
  @Render('simple-kanban-board')
  async getByUsers(@Param('name') name: string): Promise<any> {
    return await this.getByUsersRawData(name);
  }

  @Get('/by-users-like-jira/:name/raw')
  async getByUsersLikeJiraRawData(@Param('name') name: string): Promise<any> {
    const cfg = this.dynamicLoader.load(name, {
      path: this.path,
      ext: 'jsonc',
      parser: parse,
    });
    return await this.listIssuesByUsersLikeJiraWidgetDataLoaderService.load(
      cfg,
    );
  }

  @Get('/by-users-like-jira/:name')
  @Render('simple-kanban-board')
  async getByUsersLikeJira(@Param('name') name: string): Promise<any> {
    return await this.getByUsersLikeJiraRawData(name);
  }

  @Get('/by-tags/:name/raw')
  async getByTagsRawData(@Param('name') name: string): Promise<any> {
    const cfg = this.dynamicLoader.load(name, {
      path: this.path,
      ext: 'jsonc',
      parser: parse,
    });
    return await this.issuesByTagsWidgetDataLoaderService.load(cfg);
  }

  @Get('/by-tags/:name')
  @Render('simple-kanban-board')
  async getByTags(@Param('name') name: string): Promise<any> {
    return await this.getByTagsRawData(name);
  }

  @Get('/by-fields/:name/raw')
  async getByFieldsRawData(@Param('name') name: string): Promise<any> {
    const cfg = this.dynamicLoader.load(name, {
      path: this.path,
      ext: 'jsonc',
      parser: parse,
    });
    return await this.listIssuesByFieldsWidgetDataLoaderService.load(cfg);
  }

  @Get('/by-fields/:name')
  @Render('simple-kanban-board')
  async getByFields(@Param('name') name: string): Promise<any> {
    return await this.getByFieldsRawData(name);
  }
}
