"use server";

import "server-only";
import { getDb, drafts, type DraftRecord } from "@/data/db";
import { eq, and, sql } from "drizzle-orm";
import { getCurrentDid } from "@/auth";
import { generateTid } from "../tid";

// ============================================================================
// Types
// ============================================================================

export type DraftInput = {
  title: string;
  description: string;
  stops: Array<{
    tid: string;
    title: string;
    content: string;
    buttonText?: string;
    external?: {
      uri: string;
      title?: string;
      description?: string;
      thumb?: string;
    };
  }>;
  accentColor: string;
  backgroundColor: string;
};

export type SaveDraftResult = {
  success: true;
  version: number;
  warning?: "overwrote_newer";
};

// ============================================================================
// Auth Helper
// ============================================================================

async function requireAuth(): Promise<string> {
  const did = await getCurrentDid();
  if (!did) {
    throw new Error("Authentication required");
  }
  return did;
}

// ============================================================================
// Color Presets (same as client-side)
// ============================================================================

const COLOR_PRESETS = [
  { accent: "#e8a87c", background: "#fdf8f3" },
  { accent: "#c38d9e", background: "#fdf5f7" },
  { accent: "#41b3a3", background: "#f0faf9" },
  { accent: "#659dbd", background: "#f3f8fb" },
  { accent: "#e27d60", background: "#fdf6f4" },
  { accent: "#8d8741", background: "#f9f9f3" },
  { accent: "#5d5c61", background: "#f5f5f6" },
  { accent: "#7395ae", background: "#f4f7f9" },
];

function randomColorPreset() {
  return COLOR_PRESETS[Math.floor(Math.random() * COLOR_PRESETS.length)];
}

// ============================================================================
// Actions
// ============================================================================

export async function createDraft(): Promise<string> {
  const did = await requireAuth();
  const db = getDb();
  const rkey = generateTid();
  const id = `${did}:${rkey}`;
  const now = new Date();
  const colors = randomColorPreset();

  const record: DraftRecord = {
    $type: "app.sidetrail.draft",
    title: "",
    description: "",
    stops: [
      { tid: generateTid(), title: "", content: "" },
      { tid: generateTid(), title: "", content: "" },
    ],
    accentColor: colors.accent,
    backgroundColor: colors.background,
    createdAt: now.toISOString(),
    updatedAt: now.toISOString(),
  };

  await db.insert(drafts).values({
    id,
    authorDid: did,
    rkey,
    record,
    createdAt: now,
    updatedAt: now,
    version: 1,
  });

  return rkey;
}

export async function saveDraft(
  rkey: string,
  input: DraftInput,
  expectedVersion?: number,
): Promise<SaveDraftResult> {
  const did = await requireAuth();
  const db = getDb();
  const id = `${did}:${rkey}`;
  const now = new Date();

  // Check for conflict if expectedVersion provided
  let warning: "overwrote_newer" | undefined;
  if (expectedVersion !== undefined) {
    const [existing] = await db
      .select({ version: drafts.version })
      .from(drafts)
      .where(eq(drafts.id, id))
      .limit(1);

    if (existing && existing.version > expectedVersion) {
      warning = "overwrote_newer";
    }
  }

  const record: DraftRecord = {
    $type: "app.sidetrail.draft",
    title: input.title,
    description: input.description,
    stops: input.stops,
    accentColor: input.accentColor,
    backgroundColor: input.backgroundColor,
    createdAt: now.toISOString(),
    updatedAt: now.toISOString(),
  };

  // Upsert the draft
  const result = await db
    .insert(drafts)
    .values({
      id,
      authorDid: did,
      rkey,
      record,
      createdAt: now,
      updatedAt: now,
      version: 1,
    })
    .onConflictDoUpdate({
      target: drafts.id,
      set: {
        record,
        updatedAt: now,
        version: sql`${drafts.version} + 1`,
      },
    })
    .returning({ version: drafts.version });

  return warning
    ? { success: true, version: result[0].version, warning }
    : { success: true, version: result[0].version };
}

export async function deleteDraft(rkey: string): Promise<void> {
  const did = await requireAuth();
  const db = getDb();

  await db.delete(drafts).where(and(eq(drafts.authorDid, did), eq(drafts.rkey, rkey)));
}
