import { Component } from '@angular/core';
import {
  CdkDragDrop,
  CdkDropList,
  CdkDrag,
  moveItemInArray,
} from '@angular/cdk/drag-drop';
import { DetailsService } from 'src/services/details/details.service';
import { DataService } from 'src/services/data/data.service';
import { SimpleItem } from 'src/interfaces/simple-item';
import { Food } from 'src/interfaces/food';
import { SimpleItemDetailsComponent } from './simple-item-details/simple-item-details.component';
import { ModalService } from 'src/services/modal/modal.service';
import { SimpleItemModalComponent } from './simple-item-modal/simple-item-modal.component';
import { FoodDetailsComponent } from './food-details/food-details.component';

@Component({
  selector: 'app-journal-inventory',
  templateUrl: './journal-inventory.component.html',
  styleUrls: ['./journal-inventory.component.scss'],
})
export class JournalInventoryComponent {
  constructor(
    private detailsAccessor: DetailsService,
    private dataAccessor: DataService,
    private modalAccessor: ModalService
  ) {}

  public active: number = 1;

  public weaponsAndArmor: SimpleItem[] = [];
  public consumables: SimpleItem[] = [];
  public miscellaneous: SimpleItem[] = [];
  public money: any = {};
  public food: Food[] = [];

  public ngOnInit(): void {
    this.weaponsAndArmor = this.dataAccessor.weaponsAndArmor;
    this.consumables = this.dataAccessor.consumables;
    this.miscellaneous = this.dataAccessor.miscellaneous;
    this.food = this.dataAccessor.food;
    this.money = this.dataAccessor.money;
  }

  drop(event: CdkDragDrop<string[]>, list: any[], listName: string) {
    moveItemInArray(list, event.previousIndex, event.currentIndex);
    if (listName === 'weaponsAndArmor') {
      this.dataAccessor.weaponsAndArmor = list;
    } else if (listName === 'food') {
      this.dataAccessor.food = list;
    } else if (listName === 'consumables') {
      this.dataAccessor.consumables = list;
    } else if (listName === 'miscellaneous') {
      this.dataAccessor.miscellaneous = list;
    } else {
      throw new Error('Unknown list name: ' + listName);
    }
  }

  public openItemsDetails(list: any, index: number, listName: string): void {
    this.detailsAccessor.openPanel(SimpleItemDetailsComponent, {
      item: list[index],
    });
    const resultSubscription = this.detailsAccessor.result$.subscribe(
      (result) => {
        if (result.state === 'delete') {
          list.splice(index, 1);
          this.updateDatabase(listName);
        } else if (result.state === 'update') {
          this.openItemModal(true, listName, list, index);
        } else {
          throw new Error('DND-Error: Unknown state: ' + result.state);
        }
        resultSubscription.unsubscribe();
      }
    );
  }

  public openFoodDetails(index: number): void {
    this.detailsAccessor.openPanel(FoodDetailsComponent, {
      item: this.food[index],
    });
    const resultSubscription = this.detailsAccessor.result$.subscribe(
      (result) => {
        if (result.state === 'delete') {
          this.food.splice(index, 1);
          this.dataAccessor.food = this.food;
        } else if (result.state === 'update') {
          this.openFoodModal(true, index);
        } else {
          throw new Error('DND-Error: Unknown state: ' + result.state);
        }
        resultSubscription.unsubscribe();
      }
    );
  }

  public openFoodModal(isUpdate: boolean, index?: number): void {
    this.modalAccessor.openModal(SimpleItemModalComponent, {
      item:
        index !== undefined
          ? JSON.parse(JSON.stringify(this.food[index]))
          : undefined,
      isUpdate: isUpdate,
      isFood: true,
    });
    const resultSubscription = this.modalAccessor.result$.subscribe(
      (result) => {
        if (result.state === 'update') {
          this.food[index!] = result.data;
          this.updateFood();
        } else if (result.state === 'add') {
          this.food.push(result.data);
          this.updateFood();
        } else {
          throw new Error('DND-Error: Unknown state: ' + result.state);
        }
        resultSubscription.unsubscribe();
      }
    );
  }

  public openItemModal(
    isUpdate: boolean,
    listname: string,
    list?: SimpleItem[],
    index?: number
  ): void {
    this.modalAccessor.openModal(SimpleItemModalComponent, {
      item:
        list && index !== undefined
          ? JSON.parse(JSON.stringify(list[index]))
          : undefined,
      isUpdate: isUpdate,
    });
    const resultSubscription = this.modalAccessor.result$.subscribe(
      (result) => {
        if (result.state === 'update') {
          list![index!] = result.data;
          this.updateDatabase(listname);
        } else if (result.state === 'add') {
          list!.push(result.data);
          this.updateDatabase(listname);
        } else {
          throw new Error('DND-Error: Unknown state: ' + result.state);
        }
        resultSubscription.unsubscribe();
      }
    );
  }

  public addItem(): void {
    switch (this.active) {
      case 1:
        this.openItemModal(false, 'weaponsAndArmor', this.weaponsAndArmor);
        break;
      case 2:
        this.openItemModal(false, 'consumables', this.consumables);
        break;
      case 3:
        this.openItemModal(false, 'miscellaneous', this.miscellaneous);
        break;
      default:
        throw new Error('Unknown active tab: ' + this.active);
    }
  }

  // Updates

  public updateDatabase(listname: string): void {
    if (listname === 'weaponsAndArmor') {
      this.dataAccessor.weaponsAndArmor = this.weaponsAndArmor;
    } else if (listname === 'consumables') {
      this.dataAccessor.consumables = this.consumables;
    } else if (listname === 'miscellaneous') {
      this.dataAccessor.miscellaneous = this.miscellaneous;
    } else {
      throw new Error('DND-ERROR: Unknown list name: ' + listname);
    }
  }

  public updateMoney(): void {
    this.dataAccessor.money = this.money;
  }

  public updateFood(): void {
    this.dataAccessor.food = this.food;
  }
}
