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, Food } from 'src/interfaces/interfaces';
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';

@Component({
  selector: 'app-journal-inventory',
  templateUrl: './journal-inventory.component.html',
  styleUrls: ['./journal-inventory.component.scss'],
})
export class JournalInventoryComponent {
  public active: number = 1;
  public foodActive: number = 1;

  public weaponsAndArmor: SimpleItem[] = [];
  public consumables: SimpleItem[] = [];
  public miscellaneous: SimpleItem[] = [];
  public money: any = {};
  public food: Food[] = [];
  public totalWeight: number = 0;
  public maximumWeight: number = 0;
  private strength: number = 0;
  private weightModifier: number = 15;

  private speciesWeightModifierTable: any = {
    dwarf: 15,
    elf: 15,
    eladrin: 15,
    halfElf: 15,
    halfElfDetection: 15,
    halfOrc: 15,
    human: 15,
    Halfling: 7.5,
    gnome: 7.5,
    orc: 15,
    tiefling: 15,
  };

  constructor(
    private detailsAccessor: DetailsService,
    private dataAccessor: DataService,
    private modalAccessor: ModalService,
  ) {}

  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;
    this.updateWeight();
    this.weightModifier =
      this.speciesWeightModifierTable[this.dataAccessor.characterData.race];
    this.dataAccessor.strength$.subscribe((strength) => {
      this.strength = strength.value;
      this.maximumWeight = this.strength * this.weightModifier;
    });
  }

  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;
    }
  }

  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 if (result.state === 'cancel') {
          // Do nothing
        }
        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 if (result.state === 'cancel') {
          // Do nothing
        }
        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 if (result.state === 'cancel') {
          // Do nothing
        }
        resultSubscription.unsubscribe();
      },
    );
  }

  public addItem(table: string): void {
    if (table === 'items') {
      if (this.active === 1) {
        this.openItemModal(false, 'weaponsAndArmor', this.weaponsAndArmor);
      } else {
        this.openItemModal(false, 'miscellaneous', this.miscellaneous);
      }
    } else if (table === 'consumables') {
      if (this.foodActive === 1) {
        this.openFoodModal(false);
      } else if (this.foodActive === 2) {
        this.openItemModal(false, 'consumables', this.consumables);
      }
    }
  }

  // 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 if (listname === 'food') {
      this.dataAccessor.food = this.food;
    }
    this.updateWeight();
  }

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

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

  private updateWeight(): void {
    let totalWeight = 0;
    this.weaponsAndArmor.forEach((item) => {
      totalWeight += item.weight * item.quantity;
    });
    this.consumables.forEach((item) => {
      totalWeight += item.weight * item.quantity;
    });
    this.miscellaneous.forEach((item) => {
      totalWeight += item.weight * item.quantity;
    });
    this.food.forEach((item) => {
      totalWeight += item.weight * item.quantity;
    });
    const numberOfCoins =
      this.money.copper +
      this.money.silver +
      this.money.gold +
      this.money.platinum;
    totalWeight += Math.floor(numberOfCoins / 50);
    this.totalWeight = totalWeight;
  }
}
