/**
 * Spec 037 — OnboardMaestro (Fase B)
 * Durable Object: orquestra passos; delega agentes especializados (Fase C).
 */
import { DurableObject } from "cloudflare:workers";
import { vm112Get, vm112Post, type Vm112Config } from "./vm112-client";

export type OnboardState = {
  sessionId: string;
  domain: string;
  step: string;
  ligboxProjectEmail?: string;
  projectId?: string;
  dnsMode?: string;
  awaitingHuman?: string | null;
  history: string[];
};

export class OnboardMaestro extends DurableObject {
  private state: OnboardState | null = null;

  private cfg(): Vm112Config {
    const env = this.env as { VM112_API_BASE: string };
    if (!this.state?.sessionId) throw new Error("session not initialized");
    return { baseUrl: env.VM112_API_BASE, sessionId: this.state.sessionId };
  }

  private log(msg: string) {
    if (!this.state) return;
    this.state.history.push(`${new Date().toISOString()} ${msg}`);
    if (this.state.history.length > 100) this.state.history.shift();
  }

  async fetch(request: Request): Promise<Response> {
    const url = new URL(request.url);
    const path = url.pathname;

    if (path === "/init" && request.method === "POST") {
      const body = (await request.json()) as { sessionId: string; domain: string };
      this.state = {
        sessionId: body.sessionId,
        domain: body.domain.toLowerCase(),
        step: "init",
        history: [],
        awaitingHuman: null,
      };
      await this.ctx.storage.put("state", this.state);
      this.log("initialized");
      return Response.json({ ok: true, state: this.state });
    }

    const stored = (await this.ctx.storage.get<OnboardState>("state")) || this.state;
    if (!stored) return Response.json({ error: "not initialized" }, { status: 400 });
    this.state = stored;

    if (path === "/state") {
      return Response.json({ state: this.state });
    }

    if (path === "/run/proj-mail" && request.method === "POST") {
      const data = await vm112Post(this.cfg(), "/onboarding/project/provision-email", {
        domain: this.state.domain,
      });
      this.state.ligboxProjectEmail = data.ligbox_project_email as string;
      this.state.projectId = data.project_id as string;
      this.state.step = "proj_mail_done";
      this.state.awaitingHuman = "reveal_password";
      await this.ctx.storage.put("state", this.state);
      this.log(`proj-mail ${this.state.ligboxProjectEmail}`);
      return Response.json({ ok: true, data, state: this.state });
    }

    if (path === "/run/cf-zone" && request.method === "POST") {
      const prov = await vm112Post(this.cfg(), "/onboarding/dns/cloudflare/provision-zone", {
        domain: this.state.domain,
      });
      const apply = await vm112Post(this.cfg(), "/onboarding/dns/cloudflare/apply", {
        domain: this.state.domain,
        zone_id: prov.zone_id,
      });
      const verify = await vm112Get(this.cfg(), `/onboarding/dns/verify/${this.state.domain}`);
      this.state.dnsMode = (apply.dns_mode as string) || "ligbox_cf";
      this.state.step = "cf_zone_done";
      await this.ctx.storage.put("state", this.state);
      this.log("cf-zone apply+verify");
      return Response.json({ ok: true, prov, apply, verify, state: this.state });
    }

    if (path === "/human/ack" && request.method === "POST") {
      const body = (await request.json()) as { action: string };
      if (this.state.awaitingHuman === body.action) {
        this.state.awaitingHuman = null;
        await this.ctx.storage.put("state", this.state);
      }
      return Response.json({ ok: true, state: this.state });
    }

    if (path === "/run/handoff" && request.method === "POST") {
      const body = (await request.json()) as { manager_email: string };
      const data = await vm112Post(this.cfg(), "/onboarding/dns/cloudflare/handoff-manager", {
        domain: this.state.domain,
        manager_email: body.manager_email,
      });
      this.state.step = "handoff_done";
      await this.ctx.storage.put("state", this.state);
      this.log(`handoff ${body.manager_email}`);
      return Response.json({ ok: true, data, state: this.state });
    }

    return Response.json({ error: "not found" }, { status: 404 });
  }
}

/** Fase C — agentes especializados (stubs; lógica no Maestro até split) */
export class ProjMailAgent extends DurableObject {
  async fetch(request: Request): Promise<Response> {
    return Response.json({ agent: "proj-mail", status: "delegate-to-maestro" });
  }
}

export class CfZoneAgent extends DurableObject {
  async fetch(request: Request): Promise<Response> {
    return Response.json({ agent: "cf-zone", status: "delegate-to-maestro" });
  }
}

export class CfHandoffAgent extends DurableObject {
  async fetch(request: Request): Promise<Response> {
    return Response.json({ agent: "cf-handoff", status: "delegate-to-maestro" });
  }
}
