import { Inject, Injectable, Logger } from '@nestjs/common';
import type { Brain } from '@mosaicstack/brain';
import { BRAIN } from '../brain/brain.tokens.js';
import { PluginService } from '../plugin/plugin.service.js';
import { WorkspaceService } from './workspace.service.js';

export interface BootstrapProjectParams {
  name: string;
  description?: string;
  userId: string;
  teamId?: string;
  repoUrl?: string;
}

export interface BootstrapProjectResult {
  projectId: string;
  workspacePath: string;
}

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

  constructor(
    @Inject(BRAIN) private readonly brain: Brain,
    private readonly workspace: WorkspaceService,
    private readonly pluginService: PluginService,
  ) {}

  /**
   * Bootstrap a new project: create DB record + workspace directory.
   * Returns the created project with its workspace path.
   */
  async bootstrap(params: BootstrapProjectParams): Promise<BootstrapProjectResult> {
    const ownerType: 'user' | 'team' = params.teamId ? 'team' : 'user';

    this.logger.log(
      `Bootstrapping project "${params.name}" for ${ownerType} ${params.teamId ?? params.userId}`,
    );

    // 1. Create DB record
    const project = await this.brain.projects.create({
      name: params.name,
      description: params.description,
      ownerId: params.userId,
      teamId: params.teamId ?? null,
      ownerType,
    });

    // 2. Create workspace directory (includes docs structure)
    const workspacePath = await this.workspace.create(
      {
        id: project.id,
        ownerType,
        userId: params.userId,
        teamId: params.teamId ?? null,
      },
      params.repoUrl,
    );

    // 3. Create default agent config for the project
    await this.brain.agents.create({
      name: 'default',
      provider: '',
      model: '',
      projectId: project.id,
      ownerId: params.userId,
      isSystem: false,
      status: 'active',
    });

    // 4. Notify plugins so they can set up project-specific resources (e.g. Discord channel)
    try {
      for (const plugin of this.pluginService.getPlugins()) {
        if (plugin.onProjectCreated) {
          const result = await plugin.onProjectCreated({
            id: project.id,
            name: params.name,
            description: params.description,
          });
          if (result?.channelId) {
            await this.brain.projects.update(project.id, {
              metadata: { discordChannelId: result.channelId },
            });
          }
        }
      }
    } catch (err) {
      this.logger.warn(
        `Plugin project notification failed: ${err instanceof Error ? err.message : String(err)}`,
      );
    }

    this.logger.log(`Project ${project.id} bootstrapped at ${workspacePath}`);

    return { projectId: project.id, workspacePath };
  }
}
