import { Component, OnInit } from '@angular/core';

import { SearchService, AutoCompletionEntry } from 'app/search/service/search-service';
import { CloudData, CloudOptions } from 'angular-tag-cloud-module';
import Color from 'ts-color-class';

import { Router } from '@angular/router';

@Component({
  selector: 'jhi-teaser-content',
  templateUrl: './teaserContent.component.html',
  styleUrls: ['./teaserContent.component.scss'],
})
export class TeaserContentComponent implements OnInit {
  public keywords: Array<AutoCompletionEntry> = new Array<AutoCompletionEntry>();
  public contributors: Array<AutoCompletionEntry> = new Array<AutoCompletionEntry>();
  public programmingLanguages: Array<AutoCompletionEntry> = new Array<AutoCompletionEntry>();

  options: CloudOptions = {
    overflow: false,
    zoomOnHover: { scale: 1.1, transitionTime: 0.5 },
//    width: 1,
//    height: 800,
  };
  public keywordCloudData: CloudData[] = [];
  public contributorCloudData: CloudData[] = [];
  public programmingLanguageCloudData: CloudData[] = [];

  constructor(private searchService: SearchService, private router: Router) {}

  ngOnInit(): void {
    this.searchService.getKeywordsAutoComplete('').subscribe(
      (data: Array<AutoCompletionEntry>) => {
        this.keywords = data;
        this.keywordCloudData = [];
        this.keywords.forEach(kw =>
          this.keywordCloudData.push({
            text: kw.target.toString(),
            weight: Math.min(kw.hitCount.valueOf(), 10),
            color: this.randomColor(new Color('#ffaaee'), new Color('#440000')).getHex(),
          })
        );
      },
      () => {
        alert('Initialization of keywords failed');
      }
    );

    this.searchService.getProgrammingLanguageAutoComplete('').subscribe(
      (data: Array<AutoCompletionEntry>) => {
        this.programmingLanguages = data;
        this.programmingLanguageCloudData = [];
        this.programmingLanguages.forEach(pl =>
          this.programmingLanguageCloudData.push({
            text: pl.target.toString(),
            weight: Math.min(pl.hitCount.valueOf(), 10),
            color: this.randomColor(new Color('#2222ff'), new Color('#004444')).getHex(),
          })
        );
      },
      () => {
        alert('Initialization of programming languages failed');
      }
    );
    this.searchService.getContributorCreatorAutoComplete('').subscribe(
      (data: Array<AutoCompletionEntry>) => {
        this.contributors = data;
        this.contributorCloudData = [];
        this.contributors.forEach(pl =>
          this.contributorCloudData.push({
            text: pl.target.toString(),
            weight: Math.min(pl.hitCount.valueOf(), 10),
            color: this.randomColor(new Color('#aaff44'), new Color('#004400')).getHex(),
          })
        );
      },
      () => {
        alert('Initialization of contributors failed');
      }
    );
  }

  onKeywordClick(event: CloudData): void {
    this.clickKeyword(event.text);
  }

  onProgrammingLanguageClick(event: CloudData): void {
    this.clickLanguage(event.text);
  }

  onContributorClick(event: CloudData): void {
    this.clickContributor(event.text);
  }

  clickLanguage(programmingLanguage: String): void {
    this.router.navigate(['/search'], { queryParams: { pl: programmingLanguage } });
  }

  clickContributor(contributor: String): void {
    this.router.navigate(['/search'], { queryParams: { a: contributor } });
  }

  clickKeyword(keyWord: String): void {
    this.router.navigate(['/search'], { queryParams: { kw: keyWord } });
  }

  private randomColor(main: Color, deviation: Color): Color {
    const upperBound = new Color(
      Math.min(main.getRed() + deviation.getRed(), 255),
      Math.min(main.getGreen() + deviation.getGreen(), 255),
      Math.min(main.getBlue() + deviation.getBlue(), 255)
    );
    const target = new Color(
      Math.max(Math.round(upperBound.getRed() - 2 * deviation.getRed() * Math.random()), 0),
      Math.max(Math.round(upperBound.getGreen() - 2 * deviation.getGreen() * Math.random()), 0),
      Math.max(Math.round(upperBound.getBlue() - 2 * deviation.getBlue() * Math.random()), 0)
    );
    return target;
  }
}