/**
 * Service for managing per-tenant agent skills (CRUD).
 *
 * Skills are stored in the per-tenant schema table `it0_t_{tenantId}.skills`
 * so the Claude Agent SDK engine can read them directly during task execution.
 *
 * Field mapping between API and DB:
 *   API `script`  → DB `content`
 *   API `enabled` → DB `is_active`
 */
import { Injectable, Logger } from '@nestjs/common';
import { InjectDataSource } from '@nestjs/typeorm';
import { DataSource } from 'typeorm';

export interface CreateSkillDto {
  name: string;
  description?: string;
  category?: string;
  script?: string;
  tags?: string[];
  enabled?: boolean;
}

export interface UpdateSkillDto {
  name?: string;
  description?: string;
  category?: string;
  script?: string;
  tags?: string[];
  enabled?: boolean;
}

export interface SkillRecord {
  id: string;
  tenant_id: string;
  name: string;
  description: string;
  category: string;
  script: string;   // mapped from DB `content`
  tags: string[];
  enabled: boolean; // mapped from DB `is_active`
  createdAt: Date;
  updatedAt: Date;
}

@Injectable()
export class AgentSkillService {
  private readonly logger = new Logger(AgentSkillService.name);

  constructor(@InjectDataSource() private readonly dataSource: DataSource) {}

  private schema(tenantId: string): string {
    return `it0_t_${tenantId.replace(/[^a-zA-Z0-9_]/g, '')}`;
  }

  private toRecord(row: any): SkillRecord {
    return {
      id: row.id,
      tenant_id: row.tenant_id,
      name: row.name,
      description: row.description ?? '',
      category: row.category ?? 'custom',
      script: row.content ?? '',
      tags: row.tags ?? [],
      enabled: row.is_active ?? true,
      createdAt: row.created_at,
      updatedAt: row.updated_at,
    };
  }

  async findAllByTenant(tenantId: string): Promise<{ data: SkillRecord[]; total: number }> {
    const schema = this.schema(tenantId);
    const rows = await this.dataSource.query(
      `SELECT * FROM "${schema}".skills ORDER BY created_at DESC`,
    );
    const data = rows.map((r: any) => this.toRecord(r));
    return { data, total: data.length };
  }

  async create(tenantId: string, dto: CreateSkillDto): Promise<SkillRecord> {
    const schema = this.schema(tenantId);
    const rows = await this.dataSource.query(
      `INSERT INTO "${schema}".skills
         (tenant_id, name, description, category, content, tags, is_active)
       VALUES ($1, $2, $3, $4, $5, $6, $7)
       RETURNING *`,
      [
        tenantId,
        dto.name,
        dto.description ?? '',
        dto.category ?? 'custom',
        dto.script ?? '',
        dto.tags ?? [],
        dto.enabled ?? true,
      ],
    );
    return this.toRecord(rows[0]);
  }

  async update(id: string, tenantId: string, dto: UpdateSkillDto): Promise<SkillRecord | null> {
    const schema = this.schema(tenantId);
    const existing = await this.dataSource.query(
      `SELECT * FROM "${schema}".skills WHERE id = $1`,
      [id],
    );
    if (!existing.length) return null;

    const row = existing[0];
    const rows = await this.dataSource.query(
      `UPDATE "${schema}".skills SET
         name        = $1,
         description = $2,
         category    = $3,
         content     = $4,
         tags        = $5,
         is_active   = $6,
         updated_at  = now()
       WHERE id = $7
       RETURNING *`,
      [
        dto.name        ?? row.name,
        dto.description ?? row.description,
        dto.category    ?? row.category,
        dto.script      ?? row.content,
        dto.tags        ?? row.tags,
        dto.enabled     ?? row.is_active,
        id,
      ],
    );
    return this.toRecord(rows[0]);
  }

  async delete(id: string, tenantId: string): Promise<boolean> {
    const schema = this.schema(tenantId);
    const result = await this.dataSource.query(
      `DELETE FROM "${schema}".skills WHERE id = $1 RETURNING id`,
      [id],
    );
    return result.length > 0;
  }
}
