import { Component, Input, Output, EventEmitter } from '@angular/core';
import { DataService } from 'src/services/data/data.service';
import { Spell } from 'src/interfaces/spell';
import { SpellsService } from 'src/services/spells/spells.service';

@Component({
  selector: 'add-card',
  templateUrl: './add-card.component.html',
  styleUrl: './add-card.component.scss',
})
export class AddCardComponent {
  @Input() level!: number;
  @Input() alreadyUsedSpells!: any[];

  @Output() createNewSpell = new EventEmitter<any>();
  @Output() createNewSpellFromOfficial = new EventEmitter<any>();
  @Output() onSpellSelected = new EventEmitter<any>();

  public newSpellName: string = '';
  private classAvailableSpells: any[] = [];
  private allAvailableSpells: any[] = [];
  public availableSpells: any[] = [];
  public isModification: boolean | undefined;
  public state: number = 1;
  public showAll: boolean = false;

  public constructor(
    private spellsAccessor: SpellsService,
    private dataAccessor: DataService,
  ) {}

  public ngOnInit(): void {
    this.classAvailableSpells = this.spellsAccessor.getAvailableSpells(
      this.level,
      this.dataAccessor.characterData.class,
    );
    this.allAvailableSpells = this.spellsAccessor.getAvailableSpells(
      this.level,
    );
    console.log('all: ', this.allAvailableSpells);
    console.log('class: ', this.classAvailableSpells);

    this.filterSpellArray();
    this.spellsAccessor.closeSubject$.subscribe((level) => {
      if (level !== this.level) {
        this.resetThis();
      }
    });
  }

  public toggleShowAll(): void {
    this.showAll = !this.showAll;
    if (this.isModification) {
      this.filterSpellArrayForModification();
    } else {
      this.filterSpellArray();
    }
  }

  public emitNewSpell(): void {
    this.createNewSpell.emit(this.level);
    this.resetThis();
  }

  public emitNewSpellFromOfficial(spell: Spell): void {
    this.createNewSpellFromOfficial.emit(spell);
    this.resetThis();
  }

  public continueToSpellSelection(modify: boolean): void {
    this.classAvailableSpells = this.spellsAccessor.getAvailableSpells(
      this.level,
      this.dataAccessor.characterData.class,
    );
    // this.filterSpellArray();
    this.isModification = modify;
    if (modify) {
      this.filterSpellArrayForModification();
    } else {
      this.filterSpellArray();
    }
    this.closeOthers();
  }

  public spellSelected(spell: any): void {
    this.onSpellSelected.emit(spell);
    this.resetThis();
  }

  public closeOthers(): void {
    this.spellsAccessor.closeAllOthers(this.level);
  }

  public resetThis(): void {
    this.newSpellName = '';
    this.state = 1;
    this.isModification = undefined;
  }

  public filterSpellArray(): void {
    let array = this.showAll
      ? this.allAvailableSpells
      : this.classAvailableSpells;
    if (this.newSpellName.length > 0) {
      this.availableSpells = array.filter(
        (spell) =>
          (spell.german
            .toLowerCase()
            .includes(this.newSpellName.toLowerCase()) ||
            spell.english
              .toLowerCase()
              .includes(this.newSpellName.toLowerCase())) &&
          !this.alreadyUsedSpells.includes(spell.id),
      );
    } else {
      this.availableSpells = array.filter(
        (spell) => !this.alreadyUsedSpells.includes(spell.id),
      );
    }
    console.log('available: ', this.availableSpells);
  }

  public filterSpellArrayForModification(): void {
    let array = this.showAll
      ? this.allAvailableSpells
      : this.classAvailableSpells;
    if (this.newSpellName.length > 0) {
      this.availableSpells = array.filter(
        (spell) =>
          spell.german
            .toLowerCase()
            .includes(this.newSpellName.toLowerCase()) ||
          spell.english.toLowerCase().includes(this.newSpellName.toLowerCase()),
      );
    } else {
      this.availableSpells = array;
    }
    console.log('available: ', this.availableSpells);
  }
}
