import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, of, throwError } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';
import { environment } from 'src/environments/environment';
import { ClasseMercadologica } from '../models/classe-mercadologica.model';
import { FilterProduct } from '../models/filter-product.model';
import { Product } from '../models/product.model';
import { SaleProduct, Stock } from '../models/sale-product.model';
import { SaleInstallment } from './../models/sale-installment.model';

@Injectable({
  providedIn: 'root',
})
export class ProductService {
  constructor(private http: HttpClient) {}

  getSaleProducts(
    store: string,
    page: number,
    size: number,
    filterProduct: FilterProduct = null
  ): Observable<SaleProduct[]> {
    const url = environment.url + 'sales/products';

    let config = new HttpHeaders();
    config = config.set('x-store', store);
    config = config.set('x-size-count', size.toString());
    config = config.set('x-page', page.toString());

    let params = new HttpParams();
    params = params.set('url', filterProduct.urlCategory);
    params = params.set(
      'promotion',
      (filterProduct.promotion ?? false).toString()
    );
    params = params.set('offers', (filterProduct.offers ?? false).toString());
    params = params.set(
      'markdown',
      (filterProduct.markdown ?? false).toString()
    );
    params = params.set(
      'oportunity',
      (filterProduct.oportunity ?? false).toString()
    );
    params = params.set('text', filterProduct.text ?? '');

    const response = this.http.get<SaleProduct[]>(url, {
      headers: config,
      params,
    });
    console.log(response);
    return response;

    //  console.log(filterProduct);
    // if (filterProduct != null) {
    //   const response = this.http.post<SaleProduct[]>(url, filterProduct, config);
    //   console.log(response);
    //   return response;
    // } else {
    //   const response = this.http.get<SaleProduct[]>(url, config);
    //   console.log(response);
    //   return response;
    // }
  }

  getProductByDepartment(
    store: string,
    page: number,
    size: number,
    urlDepartment: string
  ): Observable<SaleProduct[]> {
    const url = environment.url + `sales/product/${urlDepartment}`;
    const config = {
      headers: {
        'x-page': page.toString(),
        'x-size-count': size.toString(),
        'x-store': store,
      },
    };

    const response = this.http.get<SaleProduct[]>(url, config);
    console.log(response);
    return response;
  }

  searchProduct(store: string, page: number, size: number, search: string) {
    console.log('Pesquisando produtos.');
    const url = environment.url + `sales/products/${search}`;
    const config = {
      headers: {
        'x-page': page.toString(),
        'x-size-count': size.toString(),
        'x-store': store,
      },
    };
    try {
      const response = this.http.get<SaleProduct[]>(url, config);
      console.log(response);
      return response;
    } catch (e) {
      console.log('Erro ao consultar produtos');
      console.log(e);
    }
  }

  getSalePromotions(
    store: string,
    page: number,
    size: number,
    filterProduct: FilterProduct = null
  ): Observable<SaleProduct[]> {
    const url = environment.url + 'sales/promotions';
    const config = {
      headers: {
        'x-page': page.toString(),
        'x-size-count': size.toString(),
        'x-store': store,
      },
    };
    try {
      if (filterProduct != null) {
        const response = this.http.post<SaleProduct[]>(
          url,
          filterProduct,
          config
        );
        console.log(response);
        return response;
      } else {
        const response = this.http.get<SaleProduct[]>(url, config);
        console.log(response);
        return response;
      }
    } catch (e) {
      console.log('Erro ao consultar promoções produtos');
      console.log(e);
    }
  }

  getProductByFilter(
    store: string,
    page: number,
    size: number,
    filterProduct: FilterProduct = null
  ): Observable<SaleProduct[]> {
    const url = `${environment.url}sales/products`;
    const config = {
      headers: {
        'x-page': page.toString(),
        'x-size-count': size.toString(),
        'x-store': store,
      },
    };

    if (filterProduct) {
      console.log('Enviando filtros para a API:', filterProduct);
      return this.http.post<SaleProduct[]>(url, filterProduct, config).pipe(
        tap((products) => console.log('Produtos retornados:', products)),
        catchError((error) => {
          console.error('Erro na busca de produtos com filtro:', error);
          return throwError(() => new Error('Erro ao buscar produtos'));
        })
      );
    } else {
      console.log('Realizando busca sem filtros');
      return this.http.get<SaleProduct[]>(url, config).pipe(
        tap((products) => console.log('Produtos retornados:', products)),
        catchError((error) => {
          console.error('Erro na busca de produtos sem filtro:', error);
          return throwError(() => new Error('Erro ao buscar produtos'));
        })
      );
    }
  }

  getSaleProduct(store: string, id: number): Observable<SaleProduct> {
    const url = environment.url + `sales/product/${id}`;
    const config = {
      headers: {
        'x-store': store,
      },
    };
    try {
      const response = this.http.get<SaleProduct>(url, config);
      return response;
    } catch (e) {
      console.log('Erro ao consultar produtos');
      console.log(e);
    }
  }

  getProduct(store: string, id: number): Observable<Product> {
    const url = environment.url + `product/${id}`;
    const config = {
      headers: {
        'x-store': store,
      },
    };
    console.log('getProduct: ' + url);
    try {
      const response = this.http.get<Product>(url, config);
      return response;
    } catch (e) {
      console.log('Erro ao consultar cadastro de produtos');
      console.log(e);
    }
  }

  getClasseMercadologica(): Observable<ClasseMercadologica[]> {
    const url = environment.url + `sales/departments`;
    const response = this.http.get<ClasseMercadologica[]>(url);
    return response;
  }

  getStocks(storeId: string, id: number): Observable<Stock[]> {
    const url = environment.url + `sales/stock/${storeId}/${id}`;
    console.log(url);
    try {
      const response = this.http.get<Stock[]>(url);
      return response;
    } catch (e) {
      console.log('Erro ao consultar estoque de produtos');
      console.log(e);
    }
  }

  getInstallment(store: string, id: number, quantity: number) {
    try {
      const url = environment.url + `sales/installment/${id}`;
      const config = new HttpHeaders().set('x-store', store);
      let params = new HttpParams();
      params = params.set('quantity', quantity.toString());
      const response = this.http.get<SaleInstallment[]>(url, {
        headers: config,
        params,
      });
      return response;
    } catch (e) {
      console.log('Erro ao consultar parcelamento de produtos');
      console.log(e);
    }
  }

  validateStock(
    productId: number,
    deliveryType: string,
    store: string,
    quantity: number
  ) {
    console.log(deliveryType);
    console.log('Quantidade do produto:' + quantity);
    if (deliveryType === 'EF') {
      return of(true);
    }
    const url = environment.url + `sales/stock/${store}/${productId}`;
    console.log('Validando estoque - url: ' + url);
    return this.http.get<Stock[]>(url).pipe(
      map((stocks) => stocks.filter((s) => s.store === store)),
      map(
        (stock) =>
          stock.length > 0 &&
          stock[0].quantity >= Number.parseFloat(quantity.toFixed(3))
      ),
      tap((valid) => console.log(valid))
    );
  }

  getProductsBuyTogether(
    idProduct: number,
    store: string
  ): Observable<SaleProduct[]> {
    const config = {
      headers: {
        'x-store': store,
      },
    };
    const response = this.http.get<SaleProduct[]>(
      `${environment.url}sales/product/bytogether/${idProduct}`,
      config
    );
    return response;
  }

  getProductSimilar(
    idProduct: number,
    store: string
  ): Observable<SaleProduct[]> {
    const config = {
      headers: {
        'x-store': store,
      },
    };
    const response = this.http.get<SaleProduct[]>(
      `${environment.url}sales/product/simil/${idProduct}`,
      config
    );
    return response;
  }
}
