import { Provide, Logger, Inject } from '@midwayjs/core';
import { ILogger } from '@midwayjs/logger';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import { NetaClawCrewEntity } from '../entity/crew.js';
import { NetaClawCrewAgentEntity } from '../entity/crew_agent.js';
import { NetaClawAgentEntity } from '../entity/agent.js';
import { CrewSchedulerService } from './crew_scheduler.js';

/**
 * 集群 CRUD 业务层
 */
@Provide()
export class CrewService {
  @Logger()
  logger: ILogger;

  @Inject()
  scheduler: CrewSchedulerService;

  @InjectEntityModel(NetaClawCrewEntity)
  crewRepo: Repository<NetaClawCrewEntity>;

  @InjectEntityModel(NetaClawCrewAgentEntity)
  crewAgentRepo: Repository<NetaClawCrewAgentEntity>;

  @InjectEntityModel(NetaClawAgentEntity)
  agentRepo: Repository<NetaClawAgentEntity>;

  /**
   * 保存画布数据并同步成员关系
   * @param crewId 集群 ID
   * @param data 包含 canvasData、delegateHints、members
   */
  async saveCanvas(
    crewId: number,
    data: {
      canvasData: Record<string, unknown>;
      delegateHints?: NetaClawCrewEntity['delegateHints'];
      masterAgentId?: number;
      members: Array<{
        agentId: number;
        role?: string;
        canvasPosition?: { x: number; y: number };
        groupName?: string;
      }>;
    },
  ): Promise<void> {
    // 更新画布数据、委派提示和主 Agent
    const updateData: Partial<NetaClawCrewEntity> = {
      canvasData: data.canvasData,
      delegateHints: data.delegateHints,
    };
    if (data.masterAgentId) {
      updateData.masterAgentId = data.masterAgentId;
    }
    await this.crewRepo.update(crewId, updateData);

    // 先删后插同步 crew_agent 成员
    await this.crewAgentRepo.delete({ crewId });

    if (data.members?.length) {
      const entities = data.members.map(m =>
        this.crewAgentRepo.create({
          crewId,
          agentId: m.agentId,
          role: m.role || '',
          canvasPosition: m.canvasPosition,
          groupName: m.groupName,
        }),
      );
      await this.crewAgentRepo.save(entities);
    }
  }

  /**
   * 获取集群详情（含成员和 Agent 信息）
   */
  async getDetail(crewId: number): Promise<any> {
    const crew = await this.crewRepo.findOneBy({ id: crewId });
    if (!crew) return null;

    const crewAgents = await this.crewAgentRepo.find({ where: { crewId } });

    // 加载每个成员的 Agent 信息
    const members = [];
    for (const ca of crewAgents) {
      const agent = await this.agentRepo.findOneBy({ id: ca.agentId });
      members.push({
        ...ca,
        agent: agent
          ? { id: agent.id, name: agent.name, label: agent.label, icon: agent.icon, description: agent.description }
          : null,
      });
    }

    // 加载主 Agent 信息
    let masterAgent = null;
    if (crew.masterAgentId) {
      const ma = await this.agentRepo.findOneBy({ id: crew.masterAgentId });
      if (ma) {
        masterAgent = { id: ma.id, name: ma.name, label: ma.label, icon: ma.icon };
      }
    }

    return { ...crew, members, masterAgent };
  }

  /**
   * 发布集群
   */
  async publish(crewId: number): Promise<void> {
    const crew = await this.crewRepo.findOneBy({ id: crewId });
    if (!crew) throw new Error(`集群 ${crewId} 不存在`);

    // 校验：主 Agent 已设置
    if (!crew.masterAgentId) {
      throw new Error('请先设置主 Agent');
    }

    // 校验：至少 2 个成员
    const memberCount = await this.crewAgentRepo.count({ where: { crewId } });
    if (memberCount < 2) {
      throw new Error('集群至少需要 2 个成员 Agent');
    }

    await this.crewRepo.update(crewId, { status: 1 });

    // 联动定时调度器
    const updatedCrew = await this.crewRepo.findOne({ where: { id: crewId } });
    if (updatedCrew) this.scheduler.registerCron(updatedCrew);
  }

  /**
   * 取消发布
   */
  async unpublish(crewId: number): Promise<void> {
    await this.crewRepo.update(crewId, { status: 0 });

    // 取消定时调度
    this.scheduler.unregisterCron(crewId);
  }
}
