import { Injectable, OnModuleInit, OnModuleDestroy, Logger } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';

@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
  private readonly logger = new Logger(PrismaService.name);

  constructor() {
    super({
      log: [
        {
          emit: 'event',
          level: 'query',
        },
        {
          emit: 'event',
          level: 'error',
        },
        {
          emit: 'event',
          level: 'info',
        },
        {
          emit: 'event',
          level: 'warn',
        },
      ],
      errorFormat: 'pretty',
    });
  }

  async onModuleInit() {
    // Setup query logging
    this.$on('query', (e) => {
      if (process.env.NODE_ENV === 'development') {
        this.logger.debug(`Query: ${e.query}`);
        this.logger.debug(`Params: ${e.params}`);
        this.logger.debug(`Duration: ${e.duration}ms`);
      }
    });

    this.$on('error', (e) => {
      this.logger.error(e);
    });

    this.$on('info', (e) => {
      this.logger.log(e);
    });

    this.$on('warn', (e) => {
      this.logger.warn(e);
    });

    await this.$connect();
    this.logger.log('Connected to database');
  }

  async onModuleDestroy() {
    await this.$disconnect();
    this.logger.log('Disconnected from database');
  }

  /**
   * Set tenant context for row-level security
   * This should be called at the beginning of each request for tenant-scoped operations
   */
  async setTenantContext(tenantId: string) {
    if (tenantId) {
      await this.$executeRaw`SET LOCAL app.current_tenant = ${tenantId}`;
    }
  }

  /**
   * Clear tenant context
   */
  async clearTenantContext() {
    await this.$executeRaw`SET LOCAL app.current_tenant = ''`;
  }
}