import { Injectable } from '@nestjs/common';
import { PrismaService } from '../../prisma/prisma.service';
import {
  TenantStrategy,
  CreateClubDto,
  Club,
} from '../interfaces/tenant-strategy.interface';

/**
 * RLS-based tenant isolation (MVP strategy).
 *
 * Uses PostgreSQL Row-Level Security with SET app.club_id
 * to enforce data isolation at the database level.
 */
@Injectable()
export class RlsTenantStrategy implements TenantStrategy {
  constructor(private readonly prisma: PrismaService) {}

  resolve(req: { user?: { clubId?: string } }): string {
    const clubId = req?.user?.clubId;
    if (!clubId) {
      throw new Error('Cannot resolve tenant: clubId is missing from request');
    }
    return clubId;
  }

  async applyIsolation(clubId: string): Promise<void> {
    await this.prisma.setTenantId(clubId);
  }

  async provision(dto: CreateClubDto): Promise<Club> {
    const club = await this.prisma.$queryRawUnsafe<Club[]>(
      `INSERT INTO clubs (name, slug, "isActive", "createdAt", "updatedAt")
       VALUES ($1, $2, true, NOW(), NOW())
       RETURNING id, name, slug, "isActive", "createdAt", "updatedAt"`,
      dto.name,
      dto.slug,
    );
    return club[0];
  }

  async deprovision(clubId: string): Promise<void> {
    await this.prisma.$executeRawUnsafe(
      `UPDATE clubs SET "isActive" = false, "updatedAt" = NOW() WHERE id = $1`,
      clubId,
    );
  }
}
