import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable, of, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { environment } from 'src/environments/environment';
import { Customer } from '../models/customer.model';
import { DeliveryTaxTable } from '../models/delivery-tax-table.model';
import { LogOrder } from '../models/log-order.model';
import { LotProduct } from '../models/lot-product.model';
import { Notify } from '../models/notify.model';
import { PaymentPlan } from '../models/payment-plan.model';
import { ResultApi } from '../models/result-api.model';
import { Rupture } from '../models/rupture.model';
import { OrderDeliveryTax } from '../sales/store/models/order-delivery-tax.model';
import { ShoppingItem } from '../sales/store/models/shopping-item';
import { Shopping } from '../sales/store/models/shopping.model';
import { MessageService } from './messages.service';

@Injectable({
  providedIn: 'root',
})
export class ShoppingService {
  private itemSubject = new BehaviorSubject<ShoppingItem>(null);
  private lotProductSubject = new BehaviorSubject<LotProduct[]>(null);
  private existsLotProduct = false;
  //  public shoppingItem: Observable<ShoppingItem>;

  constructor(
    private httpClient: HttpClient,
    private messageService: MessageService
  ) { }

  getShoppingItems(idCart: string): Observable<ShoppingItem[]> {
    if (idCart == null || idCart === '') {
      return null;
    }
    const response = this.httpClient.get<ShoppingItem[]>(
      `${environment.url}shopping/cart/${idCart}`
    );
    return response;
  }

  getShoppingItem(
    idCart: string,
    idProduct: string,
    store: string
  ): Observable<ShoppingItem[]> {
    if (idCart == null || idCart === '') {
      return null;
    }
    const config = {
      headers: {
        'x-store': store,
      },
    };
    const response = this.httpClient.get<ShoppingItem[]>(
      `${environment.url}shopping/cart/${idCart}/item/${idProduct}`,
      config
    );
    return response;
  }

  getShopping(idCart: string): Observable<Shopping> {
    if (idCart == null || idCart === '') {
      return null;
    }
    const response = this.httpClient.get<Shopping>(
      `${environment.url}shopping/${idCart}`
    );
    return response;
  }

  updateShopping(shopping: Shopping) {
    const resp = this.httpClient
      .put<Shopping>(`${environment.url}shopping/cart`, shopping)
      .pipe(
        map((response) => {
          console.log('Retorno atualização item: ' + response);
          return response;
        }),
        catchError((err) => {
          console.log('Erro ao atualizar preço do item...', err);
          return throwError(err);
        })
      );
    return resp;
  }

  updateDeliveryTax(deliveryTax: OrderDeliveryTax) {
    const resp = this.httpClient
      .put<Shopping>(`${environment.url}shopping/order/tax`, deliveryTax)
      .pipe(
        map((response) => {
          console.log('Retorno atualização item: ' + response);
          return response;
        }),
        catchError((err) => {
          console.log('Erro ao atualizar preço do item...', err);
          return throwError(err);
        })
      );
    return resp;
  }

  updatePricePaymentPlan(paymentPlan: PaymentPlan, billingId: string) {
    if (this.getCart() == null) {
      return;
    }
    console.log('Atualizando preços. (updatePricePaymentPlan)');
    const payment = {
      idPaymentPlan: paymentPlan.codplpag,
      billingId: billingId,
    };
    const idCart = this.getCart();
    const url = `${environment.url}shopping/update/payment/${idCart}`;
    console.log(
      'Url: ' +
      url +
      ' - cart: ' +
      idCart +
      ' - payment: ' +
      JSON.stringify(payment)
    );
    const resp = this.httpClient.put<ResultApi>(url, payment).pipe(
      map((response) => {
        console.log('Retorno atualização item: ' + response);
        return response;
      }),
      catchError((err) => {
        console.log('Erro ao atualizar preço do item...', err);
        return throwError(err);
      })
    );
    return resp;
  }

  createItemShopping(item: ShoppingItem) {
    const baseValue = (item?.base ?? '').toString().trim().toUpperCase();

    const colorValue = (item?.auxDescription ?? '')
      .toString()
      .trim()
      .toUpperCase();
    if (baseValue === 'S' && colorValue === '') {
      this.messageService.showModalError(
        'Produto Tintométrico',
        'Esse produto só pode ser adicionado com coloração selecionada'
      );
      return;
    }
    console.log('createItemShopping: ' + JSON.stringify(item));
    const resp = this.httpClient
      .post<ShoppingItem>(`${environment.url}shopping/item`, item)
      .pipe(
        map((response) => {
          this.setCart(response.idCart);
          localStorage.removeItem('paymentPlan');
          localStorage.removeItem('billing');
        })
      );
    return resp;
  }

  createLogShopping(logOrder: LogOrder) {
    const resp = this.httpClient
      .post(`${environment.url}shopping/log`, logOrder)
      .pipe(
        catchError((error) => {
          return of();
        })
      )
      .subscribe();
    return resp;
  }

  updatePriceItemShopping(item: ShoppingItem) {
    console.log('updatePriceItemShopping(service): ' + JSON.stringify(item));
    const resp = this.httpClient
      .put<ShoppingItem>(`${environment.url}shopping/item/discount`, item)
      .pipe(
        map((response) => {
          this.setCart(response.idCart);
        })
      );
    return resp;
  }

  updateQuantityItemShopping(item: ShoppingItem) {
    console.log('updateQuantityItemShopping(service): ' + JSON.stringify(item));
    const resp = this.httpClient
      .put<ShoppingItem>(`${environment.url}shopping/item`, item)
      .pipe(
        map((response) => {
          console.log('Retorno atualização item: ' + response);
        }),
        catchError((err) => {
          console.log('Erro ao atualizar quantidade do item...', err);
          return throwError(err);
        })
      );
    return resp;
  }

  applyDiscountOrder(order: any) {
    console.log('applyDiscountOrder(service): ' + JSON.stringify(order));
    const resp = this.httpClient
      .put<ShoppingItem[]>(`${environment.url}shopping/order/discount`, order)
      .pipe(
        map((response) => {
          console.log('Retorno atualização item: ' + response);
          return response;
        }),
        catchError((err) => {
          console.log('Erro ao atualizar quantidade do item...', err);
          return throwError(err);
        })
      );
    return resp;
  }

  deleteItemShopping(id: string) {
    const resp = this.httpClient
      .delete<ResultApi>(`${environment.url}shopping/item/delete/${id}`)
      .pipe(map((response) => response));
    return resp;
  }

  getCustomerSale() {
    const data = localStorage.getItem('customer');
    if (data === undefined || data === null) {
      return of({
        name: 'Consumidor Final',
        cpfCnpj: '111.111.111-11',
      } as Customer);
    }
    const customer = JSON.parse(data) as Customer;
    return of(customer);
  }

  setCustomerSale(customer: Customer): Observable<Customer> {
    const data = JSON.stringify(customer);
    localStorage.setItem('customer', data);
    return of(customer);
  }

  getCart() {
    return localStorage.getItem('cart');
  }

  setCart(id: string) {
    console.log('Atualizando id cart');
    return localStorage.setItem('cart', id);
  }

  createNotify(data: Notify): Observable<any> {
    const URL_API = environment.url;
    const result = this.httpClient.post<any>(`${URL_API}sales/notify`, data);
    return result;
  }

  registerRupture(data: Rupture): Observable<any> {
    const URL_API = environment.url;
    const result = this.httpClient.post<any>(`${URL_API}sales/rupture`, data);
    return result;
  }

  setShoppingItem(item: ShoppingItem) {
    localStorage.setItem('shoppingItem', JSON.stringify(item));
    this.itemSubject.next(item);
  }

  calculateDeliveryTax(dataDeliveryTax: any) {
    //cartId: string, ibgeCode: number) {
    const URL_API = environment.url;
    //const result = this.httpClient.get<DeliveryTaxTable[]>(`${URL_API}sales/calculatedeliverytax/${cartId}/${ibgeCode}`);
    const result = this.httpClient.post<DeliveryTaxTable[]>(
      `${URL_API}sales/calculatedeliverytaxorder`,
      dataDeliveryTax
    );
    return result;
  }

  getDeliveryDays(
    createDate: string,
    invoiceStoreId: string,
    placeId: Number,
    cartId
  ) {
    console.log(createDate);
    console.log(invoiceStoreId);
    console.log(placeId);
    console.log(cartId);

    const URL_API = environment.url;
    const result = this.httpClient.get<any>(
      `${URL_API}sales/deliveryDays/${createDate}/${invoiceStoreId}/${placeId}/${cartId}`
    );
    return result;
  }

  getPlacesInterior() {
    const URL_API = environment.url;
    const result = this.httpClient.get<any>(`${URL_API}sales/placesinterior`);
    return result;
  }

  getScheduleDelivery() {
    const URL_API = environment.url;
    const result = this.httpClient.get<any>(`${URL_API}shipping/schedule`);
    return result;
  }

  getLotProduct(productId: Number, customerId: Number) {
    const URL_API = environment.url;
    const result = this.httpClient.get<LotProduct[]>(
      `${URL_API}shopping/cart/lot/${productId}/${customerId}`
    );
    console.log(result);
    return result;
  }

  setListLotProduct(item: LotProduct[]) {
    localStorage.setItem('lotProduct', JSON.stringify(item));
    this.existsLotProduct = item.length > 0;
    this.lotProductSubject.next(item);
  }

  getExistsLotProduct() {
    return this.existsLotProduct;
  }

  getListLotProduct(): Observable<any> {
    return this.lotProductSubject.asObservable();
  }

  cancelShopping() {
    localStorage.removeItem('cart');
    localStorage.removeItem('customer');
    localStorage.removeItem('preCustomer');
    localStorage.removeItem('paymentPlan');
    localStorage.removeItem('billing');
    localStorage.removeItem('address');
    localStorage.removeItem('invoiceStore');
    localStorage.removeItem('partner');
    localStorage.removeItem('shoppingItem');
    localStorage.removeItem('dataDelivery');
    localStorage.removeItem('taxDelivery');
    localStorage.removeItem('authorizationTax');
    localStorage.removeItem('authorizationPartner');
  }

  public get shoppingItemValue(): Observable<ShoppingItem> {
    console.log('Item service: ' + JSON.stringify(this.itemSubject));
    return this.itemSubject.asObservable();
  }
}
