import { Injectable } from '@nestjs/common';
import { CacheService } from '../../utils/cache.service';
import { Cart } from '../interfaces/cart.interface';

@Injectable()
export class CartRepository {
  private readonly CART_TTL = 3600; // 1 hour in seconds
  private readonly CART_KEY_PREFIX = 'cart';

  constructor(private readonly cacheService: CacheService) {}

  /**
   * Get cart by user and restaurant
   */
  async findByUserAndRestaurant(userId: string, restaurantId: string): Promise<Cart | null> {
    const cacheKey = this.getCacheKey(userId, restaurantId);
    const cachedCart = await this.cacheService.get<string>(cacheKey);

    if (cachedCart) {
      try {
        const parsed: unknown = JSON.parse(cachedCart);
        if (this.isCart(parsed) && parsed.userId === userId && parsed.restaurantId === restaurantId) {
          return parsed;
        }
      } catch {
        // If parsing fails, return null
      }
    }

    return null;
  }

  /**
   * Save cart to cache
   */
  async save(cart: Cart): Promise<void> {
    const cacheKey = this.getCacheKey(cart.userId, cart.restaurantId);
    await this.cacheService.set(cacheKey, JSON.stringify(cart), this.CART_TTL);
  }

  /**
   * Delete cart from cache
   */
  async delete(userId: string, restaurantId: string): Promise<void> {
    const cacheKey = this.getCacheKey(userId, restaurantId);
    await this.cacheService.del(cacheKey);
  }

  /**
   * Generate cache key for cart
   */
  private getCacheKey(userId: string, restaurantId: string): string {
    return `${this.CART_KEY_PREFIX}:${userId}:${restaurantId}`;
  }

  /**
   * Type guard to check if an object is a Cart
   */
  private isCart(obj: unknown): obj is Cart {
    if (typeof obj !== 'object' || obj === null) {
      return false;
    }
    const cart = obj as Record<string, unknown>;
    return (
      typeof cart.userId === 'string' &&
      typeof cart.restaurantId === 'string' &&
      Array.isArray(cart.items) &&
      typeof cart.subTotal === 'number' &&
      typeof cart.itemsDiscount === 'number' &&
      typeof cart.couponDiscount === 'number' &&
      typeof cart.totalDiscount === 'number' &&
      typeof cart.tax === 'number' &&
      typeof cart.deliveryFee === 'number' &&
      typeof cart.total === 'number' &&
      typeof cart.totalItems === 'number' &&
      typeof cart.createdAt === 'string' &&
      typeof cart.updatedAt === 'string'
    );
  }
}

