import type { Transaction } from "../generated/kysely-tailordb";
import {
  CompanyNotFoundError,
  InvalidNameError,
  InvalidVersionTypeError,
  BaseVersionNotFoundError,
} from "../lib/errors.generated";
import { err, ok, type CommandContext } from "@tailor-platform/erp-kit/module";

const VALID_VERSION_TYPES = ["BUDGET", "FORECAST", "SIMULATION"] as const;

export interface CreatePlanVersionInput {
  companyId: string;
  name: string;
  type: string;
  baseVersionId?: string | null;
}

export async function run(db: Transaction, input: CreatePlanVersionInput, ctx: CommandContext) {
  void ctx;

  // Validate company exists and is ACTIVE
  const company = await db
    .selectFrom("Company" as never)
    .where("id" as never, "=", input.companyId as never)
    .selectAll()
    .executeTakeFirst();

  if (!company || (company as Record<string, unknown>).status !== "ACTIVE") {
    return err(new CompanyNotFoundError(input.companyId));
  }

  // Validate version type
  if (!VALID_VERSION_TYPES.includes(input.type as (typeof VALID_VERSION_TYPES)[number])) {
    return err(new InvalidVersionTypeError(input.type));
  }

  // Validate name is non-empty
  if (!input.name || input.name.trim() === "") {
    return err(new InvalidNameError(input.companyId));
  }

  // Validate base version if provided
  if (input.baseVersionId) {
    const baseVersion = await db
      .selectFrom("PlanVersion")
      .where("id", "=", input.baseVersionId)
      .selectAll()
      .executeTakeFirst();

    if (!baseVersion) {
      return err(new BaseVersionNotFoundError(input.baseVersionId));
    }
  }

  // Create plan version
  const planVersion = await db
    .insertInto("PlanVersion")
    .values({
      companyId: input.companyId,
      name: input.name,
      type: input.type as "BUDGET" | "FORECAST" | "SIMULATION",
      baseVersionId: input.baseVersionId ?? null,
      createdAt: new Date(),
      updatedAt: null,
    })
    .returningAll()
    .executeTakeFirst();

  return ok({ planVersion: planVersion! });
}
