import { Inject, Injectable, NotFoundException } from "@nestjs/common";
import { Logger } from "nestjs-pino";
import { randomUUID } from "crypto";
import { CacheService } from "@bff/infra/cache/cache.service.js";
import type { CheckoutBuildCartRequest, CheckoutCart } from "@customer-portal/domain/orders";

type CheckoutSessionRecord = {
  request: CheckoutBuildCartRequest;
  cart: CheckoutCart;
  createdAt: string;
  expiresAt: string;
};

@Injectable()
export class CheckoutSessionService {
  private readonly ttlSeconds = 2 * 60 * 60; // 2 hours
  private readonly keyPrefix = "checkout-session";

  constructor(
    private readonly cache: CacheService,
    @Inject(Logger) private readonly logger: Logger
  ) {}

  async createSession(request: CheckoutBuildCartRequest, cart: CheckoutCart) {
    const sessionId = randomUUID();
    const createdAt = new Date();
    const expiresAt = new Date(createdAt.getTime() + this.ttlSeconds * 1000);

    const record: CheckoutSessionRecord = {
      request,
      cart,
      createdAt: createdAt.toISOString(),
      expiresAt: expiresAt.toISOString(),
    };

    const key = this.buildKey(sessionId);
    await this.cache.set(key, record, this.ttlSeconds);

    this.logger.debug("Checkout session created", { sessionId, expiresAt: record.expiresAt });

    return {
      sessionId,
      expiresAt: record.expiresAt,
    };
  }

  async getSession(sessionId: string): Promise<CheckoutSessionRecord> {
    const key = this.buildKey(sessionId);
    const record = await this.cache.get<CheckoutSessionRecord>(key);
    if (!record) {
      throw new NotFoundException("Checkout session not found");
    }
    return record;
  }

  async deleteSession(sessionId: string): Promise<void> {
    const key = this.buildKey(sessionId);
    await this.cache.del(key);
  }

  private buildKey(sessionId: string): string {
    return `${this.keyPrefix}:${sessionId}`;
  }
}
