import { inject, Injectable, signal } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { catchError, map, Observable, tap } from 'rxjs';

import { ApiResponse } from '../api-response.interface';
import { TenantService } from '../tenant.service';
import { Cart } from './cart.interface';

@Injectable({
  providedIn: 'root'
})
export class CartService {
  private readonly http = inject(HttpClient);
  private readonly tenantService = inject(TenantService);

  private readonly cartState = signal<Cart | null>(null);
  readonly cart = this.cartState.asReadonly();

  private readonly isUpdatingState = signal<boolean>(false);
  readonly isUpdating = this.isUpdatingState.asReadonly();

  private get tenantApiUrl(): string {
    return this.tenantService.getTenantApiUrl();
  }

  clearCart(): void {
    this.cartState.set({
      id: null,
      tenant_codigo: this.tenantService.tenant()?.codigo ?? '',
      status: 'active',
      items: [],
      subtotal: '0.00'
    });
  }

  loadCart(): Observable<Cart> {
    return this.http
      .get<ApiResponse<Cart>>(`${this.tenantApiUrl}/cart`, {
        withCredentials: true
      })
      .pipe(
        map((response) => response.data),
        tap((cart) => this.cartState.set(cart))
      );
  }

  addItem(productVariantId: number, cantidad: number): Observable<ApiResponse<Cart>> {
    this.isUpdatingState.set(true);
    return this.http
      .post<ApiResponse<Cart>>(
        `${this.tenantApiUrl}/cart/items`,
        { product_variant_id: productVariantId, cantidad },
        { withCredentials: true }
      )
      .pipe(
        tap((response) => {
          this.cartState.set(response.data);
          this.isUpdatingState.set(false);
        }),
        catchError((error) => {
          this.isUpdatingState.set(false);
          throw error;
        })
      );
  }

  updateItemQuantity(productVariantId: number, cantidad: number): Observable<ApiResponse<Cart>> {
    this.isUpdatingState.set(true);
    return this.http
      .patch<ApiResponse<Cart>>(
        `${this.tenantApiUrl}/cart/items/${productVariantId}`,
        { cantidad },
        { withCredentials: true }
      )
      .pipe(
        tap((response) => {
          this.cartState.set(response.data);
          this.isUpdatingState.set(false);
        }),
        catchError((error) => {
          this.isUpdatingState.set(false);
          throw error;
        })
      );
  }

  removeItem(productVariantId: number): Observable<ApiResponse<Cart>> {
    this.isUpdatingState.set(true);
    return this.http
      .delete<ApiResponse<Cart>>(
        `${this.tenantApiUrl}/cart/items/${productVariantId}`,
        { withCredentials: true }
      )
      .pipe(
        tap((response) => {
          this.cartState.set(response.data);
          this.isUpdatingState.set(false);
        }),
        catchError((error) => {
          this.isUpdatingState.set(false);
          throw error;
        })
      );
  }
}
