import { Component, EventEmitter, Input, Output } from '@angular/core';
import { forkJoin, map } from 'rxjs';
import { FoodCardProps } from 'src/app/shared/interfaces/components/cards/food-card/food-card.interface';
import {
  RecipeFilters,
  RecipeOrder,
} from 'src/app/shared/interfaces/services/api-fit/request/recipe.interface';
import { RecipeTag } from 'src/app/shared/interfaces/services/api-fit/response/recipe.interface';
import { ApiFitService } from 'src/app/shared/services/api-fit/api-fit.service';

@Component({
  selector: 'app-filter-recipe',
  templateUrl: './filter-recipe.component.html',
  styleUrls: ['./filter-recipe.component.scss'],
})
export class FilterRecipeComponent {
  @Input() filter!: RecipeFilters;
  @Input() isVisible = false;

  @Output() filterChange = new EventEmitter<RecipeFilters>();
  @Output() onFilter = new EventEmitter<RecipeFilters>();
  @Output() isVisibleChange = new EventEmitter<boolean>();

  orderOptions: { value: RecipeOrder; label: string }[] = [
    {
      value: 'id.desc',
      label: 'Mais recentes',
    },
    {
      value: 'id.asc',
      label: 'Mais antigas',
    },
    {
      value: 'likes.desc',
      label: 'Mais curtidas',
    },
    {
      value: 'likes.asc',
      label: 'Menos curtidas',
    },
    {
      value: 'name.asc',
      label: 'A-Z',
    },
    {
      value: 'name.desc',
      label: 'Z-A',
    },
    {
      value: 'calories.desc',
      label: 'Mais calóricas',
    },
    {
      value: 'calories.asc',
      label: 'Menos calóricas',
    },
    {
      value: 'servings.desc',
      label: 'Mais porções',
    },
    {
      value: 'servings.asc',
      label: 'Menos porções',
    },
  ];
  orderLabels = this.orderOptions.map((option) => option.label);
  orderSelectedLabel = this.orderOptions[0].label;

  isSearchingTags = false;
  tagsSelected: RecipeTag[] = [];

  isSearchingIngredients = false;
  ingredientsSelected: FoodCardProps[] = [];

  constructor(private apiFitService: ApiFitService) {}

  ngOnInit() {
    this.loadElementsFromFilter();
  }

  loadElementsFromFilter() {
    if (this.filter.tags_ids.length) {
      if (!Array.isArray(this.filter.tags_ids)) {
        this.filter.tags_ids = [this.filter.tags_ids];
      }

      const tagsRequests = this.filter.tags_ids.map((tagId) =>
        this.apiFitService.getTagById(tagId),
      );

      forkJoin(tagsRequests).subscribe({
        next: (d) => (this.tagsSelected = d.map((res) => res.data)),
      });
    }

    if (this.filter.ingredients_ids.length) {
      if (!Array.isArray(this.filter.ingredients_ids)) {
        this.filter.ingredients_ids = [this.filter.ingredients_ids];
      }

      const ingredientsRequests = this.filter.ingredients_ids.map(
        (ingredientId) => this.apiFitService.getFoodById(ingredientId),
      );

      forkJoin(ingredientsRequests)
        .pipe(map((res) => res.map((r) => r.data)))
        .subscribe({
          next: (i) =>
            (this.ingredientsSelected = i.map((i) => {
              return {
                ...i,
                kcal: i.kcalPer100,
                quantity: 100,
                type: 'food',
              };
            })),
        });
    }
  }

  addTags(tags: RecipeTag[]) {
    this.tagsSelected = tags;
    this.filter.tags_ids = tags.map((t) => t.id);
    this.filterChange.emit(this.filter);

    this.isSearchingTags = false;
  }

  removeTag(tag: RecipeTag) {
    this.tagsSelected = this.tagsSelected.filter((t) => t.id !== tag.id);

    if (!Array.isArray(this.filter.tags_ids)) {
      this.filter.tags_ids = [];
      this.filterChange.emit(this.filter);
      return;
    }

    const index = this.filter.tags_ids.findIndex(
      (i) => parseInt(i.toString()) === tag.id,
    );

    if (index === -1) return;

    this.filter.tags_ids.splice(index, 1);
    this.filterChange.emit(this.filter);
  }

  changeOrder(label: string) {
    const order = this.orderOptions.find((option) => option.label === label);

    if (!order) return;
    this.filter.order_by = order.value;

    this.filterChange.emit(this.filter);
  }

  addIngredient(ingredient: FoodCardProps) {
    if (!this.ingredientsSelected.find((i) => i.id === ingredient.id)) {
      this.ingredientsSelected.push({
        ...ingredient,
        quantity: 100,
        kcal: ingredient.kcal,
        type: 'food',
      });

      this.filter.ingredients_ids.push(ingredient.id);
      this.filterChange.emit(this.filter);
    }

    this.isSearchingIngredients = false;
  }

  removeIngredient(ingredient: FoodCardProps) {
    this.ingredientsSelected = this.ingredientsSelected.filter(
      (i) => i.id !== ingredient.id,
    );

    if (!Array.isArray(this.filter.ingredients_ids)) {
      this.filter.ingredients_ids = [];
      this.filterChange.emit(this.filter);
      return;
    }

    const index = this.filter.ingredients_ids.findIndex(
      (i) => parseInt(i.toString()) === ingredient.id,
    );
    if (index === -1) return;

    this.filter.ingredients_ids.splice(index, 1);
    this.filterChange.emit(this.filter);
  }

  clearFilter() {
    this.filter = {
      ...this.filter,
      min_calorie_content_per_portion: 0,
      max_calorie_content_per_portion: 0,
      tags_ids: [],
      ingredients_ids: [],
      order_by: 'id.desc',
      servings: 0,
    };
    this.orderSelectedLabel = this.orderOptions[0].label;
    this.tagsSelected = [];
    this.ingredientsSelected = [];

    this.filterChange.emit(this.filter);
  }

  handleFilterClick() {
    this.filter.page = 1;

    this.onFilter.emit(this.filter);
    this.isVisibleChange.emit(false);
  }

  close() {
    this.isVisibleChange.emit(false);
  }
}
