import {Component, inject, OnDestroy, OnInit, signal} from '@angular/core';
import {ActivatedRoute, Params, Router} from '@angular/router';
import {filter, Observable, of, Subscription, switchMap} from 'rxjs';
import {FormBuilder, ReactiveFormsModule, Validators} from '@angular/forms';
import {MonsterType} from '../../utils/monster.utils';
import {PlayingCardComponent} from '../../components/playing-card/playing-card.component';
import {Monster} from '../../models/monster.model';
import {MonsterService} from '../../services/monster/monster.service';
import {MatButtonModule} from '@angular/material/button';
import {MatFormField, MatLabel} from '@angular/material/form-field';
import {MatInput} from '@angular/material/input';
import {MatOption, MatSelect} from '@angular/material/select';
import {MatDialog} from '@angular/material/dialog';
import {
  DeleteMonsterConfirmationDialogComponent
} from '../../components/delete-monster-confirmation-dialog/delete-monster-confirmation-dialog.component';

@Component({
  selector: 'app-monster',
  standalone: true,
  imports: [
    ReactiveFormsModule,
    PlayingCardComponent,
    MatButtonModule,
    MatFormField,
    MatInput,
    MatLabel,
    MatSelect,
    MatOption
  ],
  templateUrl: './monster.component.html',
  styleUrl: './monster.component.css'
})
export class MonsterComponent implements OnInit, OnDestroy {

  private readonly route: ActivatedRoute = inject(ActivatedRoute);
  private readonly router: Router = inject(Router);
  private readonly fb: FormBuilder = inject(FormBuilder);
  private readonly dialog: MatDialog = inject(MatDialog);

  private readonly monsterService = inject(MonsterService);

  subscriptions: Subscription = new Subscription();

  formGroup = this.fb.group({
    name: ['', [
      Validators.required
    ]],
    image: ['', [
      Validators.required
    ]],
    type: [MonsterType.ELECTRIC, [
      Validators.required
    ]],
    hp: [0, [
      Validators.required,
      Validators.min(1),
      Validators.max(200)
    ]],
    figureCaption: ['', [
      Validators.required
    ]],
    attackName: ['', [
      Validators.required
    ]],
    attackStrength: [0, [
      Validators.required,
      Validators.min(1),
      Validators.max(200)
    ]],
    attackDescription: ['', [
      Validators.required
    ]],
  });


  monster = Object.assign(new Monster(), this.formGroup.value);
  monsterTypes = Object.values(MonsterType);
  monsterId = -1;

  ngOnInit() {
    const formValuesSubscription = this.formGroup.valueChanges.subscribe(data => {
      this.monster = Object.assign(new Monster(), data);
    });
    this.subscriptions.add(formValuesSubscription);
    const routeSubscription = this.route.params.pipe(
      switchMap(params => {
        if (params['id']) {
          this.monsterId = parseInt(params['id']);
          return this.monsterService.get(this.monsterId) ?? of(null)
        } else {
          return of(null);
        }
      })
    ).subscribe((monster) => {
      if (monster) {
        this.monster = monster;
        this.formGroup.patchValue(monster);
      }
    });
    this.subscriptions.add(routeSubscription);
  }

  ngOnDestroy() {
    this.subscriptions?.unsubscribe();
  }

  hasNextMonster(): boolean {
    return this.monsterService.get(this.monsterId + 1) !== undefined;
  }

  previous() {
    let previousId = this.monsterId;
    previousId--;
    if (previousId < 1) previousId = 1;
    this.router.navigate(['/monster/' + previousId]).then();
  }

  next() {
    let nextId = this.monsterId;
    if (nextId === -1 || nextId === 0) {
      nextId = 0;
    }
    nextId++;
    this.router.navigate(['/monster/' + nextId]).then();
  }

  deleteMonster() {
    const dialogRef = this.dialog.open(DeleteMonsterConfirmationDialogComponent);
    const deleteSubscription = dialogRef.afterClosed().pipe(
      filter(confirmation => confirmation),
      switchMap(_ => this.monsterService.delete(this.monsterId))
    ).subscribe(_ => {
      this.navigateBack();
    });
    this.subscriptions.add(deleteSubscription);
  }

  navigateBack() {
    this.router.navigate(['/home']).then();
  }

  submit(event: Event) {
    event.preventDefault();
    let saveObservable: Observable<Monster>;
    if (this.monsterId === -1) {
      saveObservable = this.monsterService.add(this.monster);
    } else {
      this.monster.id = this.monsterId;
      saveObservable = this.monsterService.update(this.monster);
    }
    const saveSubscription = saveObservable.subscribe(_ => {
      this.navigateBack();
    });
    this.subscriptions.add(saveSubscription);
  }

  isFieldValid(fieldName: string): boolean {
    const formControl = this.formGroup.get(fieldName);
    return formControl ? formControl.invalid && (formControl.dirty || formControl.touched) : false;
  }

  onFileChange(event: any) {
    const reader = new FileReader();
    if (event.target.files && event.target.files.length) {
      const [file] = event.target.files;
      reader.readAsDataURL(file);
      reader.onload = () => {
        this.formGroup.patchValue({
          image: reader.result as string
        })
      }
    }
  }
}
