/**
 * AgentProject service —— ChatGPT-style 用户自创 folder/workspace。
 *
 * 与 FF AI Workspace 业务项目（车型/营销）解耦。删除项目时把内含 session 的 projectId 置 null
 * （保 session，落到"全部会话"桶），不级联删 session。
 */

import { Injectable } from '@nestjs/common';
import { PrismaService } from '@core/database/prisma/prisma.service';
import { SkipAssertAccess } from '@common/decorators/skip-assert-access.decorator';
import type { AgentProject } from '@prisma/client';
import { assertOwn } from '../utils/ownership.util';
import { assertNonEmptyString } from '../utils/validation.util';

const NAME_MAX = 120;

export interface CreateProjectInput {
  organizationId: string;
  createdById: string;
  name: string;
  icon?: string;
  color?: string;
  instructions?: string;
}

export interface UpdateProjectInput {
  name?: string;
  icon?: string;
  color?: string;
  instructions?: string;
}

@Injectable()
export class AgentProjectsService {
  constructor(private readonly prisma: PrismaService) {}

  async list(organizationId: string, createdById: string): Promise<AgentProject[]> {
    return this.prisma.agentProject.findMany({
      where: { organizationId, createdById },
      orderBy: { updatedAt: 'desc' },
    });
  }

  async create(input: CreateProjectInput): Promise<AgentProject> {
    const name = assertNonEmptyString(input.name, 'name', NAME_MAX);
    return this.prisma.agentProject.create({
      data: {
        organizationId: input.organizationId,
        createdById: input.createdById,
        name,
        icon: input.icon ?? null,
        color: input.color ?? null,
        instructions: input.instructions ?? null,
      },
    });
  }

  async update(
    id: string,
    organizationId: string,
    createdById: string,
    patch: UpdateProjectInput,
  ): Promise<AgentProject> {
    await this.assertOwnProject(id, organizationId, createdById);
    let name: string | undefined;
    if (patch.name !== undefined) {
      name = assertNonEmptyString(patch.name, 'name', NAME_MAX);
    }
    return this.prisma.agentProject.update({
      where: { id },
      data: {
        ...(name !== undefined ? { name } : {}),
        ...(patch.icon !== undefined ? { icon: patch.icon || null } : {}),
        ...(patch.color !== undefined ? { color: patch.color || null } : {}),
        ...(patch.instructions !== undefined ? { instructions: patch.instructions || null } : {}),
      },
    });
  }

  /** 单事务：先把 session.projectId 置 null，再删项目。避免孤立 projectId */
  @SkipAssertAccess('入口即 assertOwnProject(projectId, org, user)，写动作前已校验归属')
  async remove(id: string, organizationId: string, createdById: string): Promise<{ ok: true }> {
    await this.assertOwnProject(id, organizationId, createdById);
    await this.prisma.$transaction([
      this.prisma.agentSession.updateMany({
        where: { projectId: id, organizationId },
        data: { projectId: null },
      }),
      this.prisma.agentProject.delete({ where: { id } }),
    ]);
    return { ok: true };
  }

  private async assertOwnProject(id: string, organizationId: string, createdById: string): Promise<AgentProject> {
    const p = await this.prisma.agentProject.findUnique({ where: { id } });
    return assertOwn(p, organizationId, createdById, { entityLabel: 'project' });
  }
}
