"use server";

import { revalidatePath } from "next/cache";
import { api } from "../../../convex/_generated/api";
import { m } from "@/lib/convex-server";
import { run, type ActionResult } from "@/lib/action";
import type { TASK_STATUSES, MAINTENANCE_STATUSES } from "@/lib/domain";

export interface TaskInput {
  title: string;
  description?: string | null;
  type?: string;
  apartmentId?: string | null;
  reservationId?: string | null;
  customerId?: string | null;
  assigneeId?: string | null;
  priority?: string;
  dueDate?: string | null;
  dueTime?: string | null;
  notes?: string | null;
}
const nul = <T,>(x: T | "" | undefined | null) => (x === "" || x === undefined ? null : x);
const rev = () => {
  for (const p of ["/tasks", "/cleaning", "/maintenance", "/dashboard", "/apartments", "/calendar"]) revalidatePath(p);
};

export async function createTask(input: TaskInput): Promise<ActionResult<{ id: string }>> {
  return run(async () => {
    const r = await m(api.operations.createTask, { title: input.title, description: nul(input.description), type: input.type, apartmentId: nul(input.apartmentId), reservationId: nul(input.reservationId), customerId: nul(input.customerId), assigneeId: nul(input.assigneeId), priority: input.priority, dueDate: nul(input.dueDate), dueTime: nul(input.dueTime), notes: nul(input.notes) });
    rev();
    return r;
  });
}

export async function updateTask(id: string, input: Partial<TaskInput> & { status?: (typeof TASK_STATUSES)[number] }): Promise<ActionResult<undefined>> {
  return run(async () => {
    const args: Record<string, unknown> = { id, status: input.status };
    for (const k of ["title", "type", "priority"] as const) if (input[k] !== undefined) args[k] = input[k];
    for (const k of ["description", "apartmentId", "reservationId", "customerId", "assigneeId", "dueDate", "dueTime", "notes"] as const) if (input[k] !== undefined) args[k] = nul(input[k]);
    await m(api.operations.updateTask, args);
    rev();
    return undefined;
  });
}

export async function assignCleaning(cleaningTaskId: string, assigneeId: string | null): Promise<ActionResult<undefined>> {
  return run(async () => {
    await m(api.operations.assignCleaning, { cleaningTaskId, assigneeId });
    rev();
    return undefined;
  });
}

export interface MaintenanceInput {
  apartmentId: string;
  title: string;
  category?: string;
  priority?: string;
  description?: string | null;
  assigneeId?: string | null;
  cost?: number;
  blocksApartment?: boolean;
  startDate?: string | null;
  completionDate?: string | null;
}

export async function createMaintenance(input: MaintenanceInput): Promise<ActionResult<{ id: string; code: string }>> {
  return run(async () => {
    const r = await m(api.operations.createMaintenance, { apartmentId: input.apartmentId, title: input.title, category: input.category, priority: input.priority, description: nul(input.description), assigneeId: nul(input.assigneeId), cost: input.cost === undefined ? undefined : Number(input.cost), blocksApartment: input.blocksApartment, startDate: nul(input.startDate), completionDate: nul(input.completionDate) });
    rev();
    return r;
  });
}

export async function updateMaintenance(id: string, input: Partial<MaintenanceInput> & { status?: (typeof MAINTENANCE_STATUSES)[number] }): Promise<ActionResult<undefined>> {
  return run(async () => {
    const args: Record<string, unknown> = { id, status: input.status };
    for (const k of ["title", "category", "priority", "blocksApartment"] as const) if (input[k] !== undefined) args[k] = input[k];
    if (input.cost !== undefined) args.cost = Number(input.cost);
    for (const k of ["description", "assigneeId", "startDate", "completionDate"] as const) if (input[k] !== undefined) args[k] = nul(input[k]);
    await m(api.operations.updateMaintenance, args);
    rev();
    return undefined;
  });
}
