import type { PrismaClient, Prompt } from '@prisma/client';

export interface PromptCreateInput {
  name: string;
  content: string;
  projectId?: string;
  agentId?: string;
  priority?: number;
  linkTarget?: string;
}

export interface PromptUpdateInput {
  content?: string;
  priority?: number;
  summary?: string;
  chapters?: string[];
  semver?: string;
  currentRevisionId?: string | null;
}

export interface IPromptRepository {
  findAll(projectId?: string): Promise<Prompt[]>;
  findGlobal(): Promise<Prompt[]>;
  findByAgent(agentId: string): Promise<Prompt[]>;
  findById(id: string): Promise<Prompt | null>;
  findByNameAndProject(name: string, projectId: string | null): Promise<Prompt | null>;
  findByNameAndAgent(name: string, agentId: string | null): Promise<Prompt | null>;
  create(data: PromptCreateInput): Promise<Prompt>;
  update(id: string, data: PromptUpdateInput): Promise<Prompt>;
  delete(id: string): Promise<void>;
}

export class PromptRepository implements IPromptRepository {
  constructor(private readonly prisma: PrismaClient) {}

  async findAll(projectId?: string): Promise<Prompt[]> {
    const include = { project: { select: { name: true } } };
    if (projectId !== undefined) {
      // Project-scoped + global prompts
      return this.prisma.prompt.findMany({
        where: { OR: [{ projectId }, { projectId: null, agentId: null }] },
        include,
        orderBy: { name: 'asc' },
      });
    }
    return this.prisma.prompt.findMany({ include, orderBy: { name: 'asc' } });
  }

  async findGlobal(): Promise<Prompt[]> {
    return this.prisma.prompt.findMany({
      where: { projectId: null, agentId: null },
      include: { project: { select: { name: true } } },
      orderBy: { name: 'asc' },
    });
  }

  async findByAgent(agentId: string): Promise<Prompt[]> {
    return this.prisma.prompt.findMany({
      where: { agentId },
      include: { agent: { select: { name: true } } },
      orderBy: { name: 'asc' },
    });
  }

  async findById(id: string): Promise<Prompt | null> {
    return this.prisma.prompt.findUnique({
      where: { id },
      include: {
        project: { select: { name: true } },
        agent: { select: { name: true } },
      },
    });
  }

  async findByNameAndProject(name: string, projectId: string | null): Promise<Prompt | null> {
    return this.prisma.prompt.findUnique({
      where: { name_projectId: { name, projectId: projectId ?? '' } },
    });
  }

  async findByNameAndAgent(name: string, agentId: string | null): Promise<Prompt | null> {
    return this.prisma.prompt.findUnique({
      where: { name_agentId: { name, agentId: agentId ?? '' } },
    });
  }

  async create(data: PromptCreateInput): Promise<Prompt> {
    return this.prisma.prompt.create({ data });
  }

  async update(id: string, data: PromptUpdateInput): Promise<Prompt> {
    return this.prisma.prompt.update({ where: { id }, data });
  }

  async delete(id: string): Promise<void> {
    await this.prisma.prompt.delete({ where: { id } });
  }
}
