"use server";

import { revalidatePath } from "next/cache";
import { getServerSession } from "next-auth";
import { authOptions } from "@/lib/auth";
import { db } from "@/db";

async function requireAdmin() {
  const session = await getServerSession(authOptions);
  if (!session) throw new Error("Non autorizzato");
}
import { time_entries, projects } from "@/db/schema";
import { eq, isNull, asc } from "drizzle-orm";
import { nanoid } from "nanoid";

export async function startTimer(projectId: string): Promise<{ entryId: string }> {
  await requireAdmin();
  // Stop any currently running session before starting a new one
  const running = await db
    .select({ id: time_entries.id })
    .from(time_entries)
    .where(isNull(time_entries.ended_at));

  for (const r of running) {
    const now = new Date();
    const entry = await db
      .select({ started_at: time_entries.started_at })
      .from(time_entries)
      .where(eq(time_entries.id, r.id))
      .limit(1);
    if (entry[0]) {
      const secs = Math.round((now.getTime() - new Date(entry[0].started_at).getTime()) / 1000);
      await db
        .update(time_entries)
        .set({ ended_at: now, duration_seconds: secs })
        .where(eq(time_entries.id, r.id));
    }
  }

  const id = nanoid();
  await db.insert(time_entries).values({ id, project_id: projectId });
  revalidatePath("/admin");
  revalidatePath("/admin/projects");
  revalidatePath(`/admin/projects/${projectId}`);
  return { entryId: id };
}

export async function startTimerForClient(clientId: string): Promise<{ entryId: string }> {
  await requireAdmin();
  const projectRows = await db
    .select({ id: projects.id })
    .from(projects)
    .where(eq(projects.client_id, clientId))
    .orderBy(asc(projects.created_at))
    .limit(1);
  const projectId = projectRows[0]?.id;
  if (!projectId) throw new Error("Nessun progetto trovato per questo cliente");
  return startTimer(projectId);
}

export async function stopTimer(entryId: string): Promise<void> {
  await requireAdmin();
  const rows = await db
    .select({ started_at: time_entries.started_at, project_id: time_entries.project_id })
    .from(time_entries)
    .where(eq(time_entries.id, entryId))
    .limit(1);

  if (!rows[0]) return;

  const now = new Date();
  const secs = Math.round((now.getTime() - new Date(rows[0].started_at).getTime()) / 1000);
  await db
    .update(time_entries)
    .set({ ended_at: now, duration_seconds: secs })
    .where(eq(time_entries.id, entryId));

  revalidatePath("/admin");
  revalidatePath("/admin/projects");
  revalidatePath(`/admin/projects/${rows[0].project_id}`);
}

/**
 * Inserts a manually entered time block (already closed).
 * duration_seconds = minutes * 60
 * ended_at = started_at + duration_seconds
 * @param projectId  project to record time against
 * @param minutes    duration in minutes (must be > 0)
 * @param startedAt  optional ISO date string — defaults to start of current day
 */
export async function addManualTimeEntry(
  projectId: string,
  minutes: number,
  startedAt?: string
): Promise<void> {
  await requireAdmin();
  if (!Number.isFinite(minutes) || minutes <= 0) throw new Error("Minuti non validi");

  const start = startedAt ? new Date(startedAt) : new Date();
  if (isNaN(start.getTime())) throw new Error("Data non valida");

  const durationSeconds = Math.round(minutes * 60);
  const end = new Date(start.getTime() + durationSeconds * 1000);

  await db.insert(time_entries).values({
    id: nanoid(),
    project_id: projectId,
    started_at: start,
    ended_at: end,
    duration_seconds: durationSeconds,
  });

  revalidatePath("/admin");
  revalidatePath("/admin/projects");
  revalidatePath(`/admin/projects/${projectId}`);
}

/**
 * Deletes a time entry by id, scoped to the given project (guard against
 * cross-project deletions).
 */
export async function deleteTimeEntry(entryId: string, projectId: string): Promise<void> {
  await requireAdmin();
  await db
    .delete(time_entries)
    .where(eq(time_entries.id, entryId));

  revalidatePath("/admin");
  revalidatePath("/admin/projects");
  revalidatePath(`/admin/projects/${projectId}`);
}

