import type { Database } from "bun:sqlite";
import type { Request as ExRequest } from "express";
import { HttpError } from "../httpErrors";
import type {
  CreateOrganizationRequest,
  CreateProjectRequest,
  CreateTaskRequest,
  CreateUserRequest,
  UpdateTaskRequest,
} from "../models";

export function getDatabase(request: ExRequest): Database {
  return request.app.locals.db as Database;
}

function optionalText(value: unknown) {
  return typeof value === "string" ? value.trim() : undefined;
}

function requiredText(value: unknown, fieldName: string) {
  if (typeof value !== "string" || value.trim() === "") {
    throw new HttpError(400, `${fieldName} is required.`);
  }

  return value.trim();
}

function nullableText(value: unknown) {
  if (typeof value === "string") {
    return value.trim();
  }

  return value === null ? null : undefined;
}

function nullableInteger(value: unknown) {
  if (typeof value === "number") {
    return Math.trunc(value);
  }

  return value === null ? null : undefined;
}

export function normalizeCreateTask(body: CreateTaskRequest): CreateTaskRequest {
  return {
    orgId: requiredText(body.orgId, "orgId"),
    projectId: requiredText(body.projectId, "projectId"),
    assigneeUserId:
      typeof body.assigneeUserId === "string" ? body.assigneeUserId.trim() : null,
    title: requiredText(body.title, "title"),
    description: optionalText(body.description),
    status: optionalText(body.status),
    priority: optionalText(body.priority),
    storyPoints: nullableInteger(body.storyPoints),
    dueDate:
      typeof body.dueDate === "string"
        ? body.dueDate
        : body.dueDate === null
          ? null
          : undefined,
  };
}

export function normalizeCreateOrganization(
  body: CreateOrganizationRequest,
): CreateOrganizationRequest {
  return {
    slug: requiredText(body.slug, "slug"),
    name: requiredText(body.name, "name"),
    plan: requiredText(body.plan, "plan"),
    industry: requiredText(body.industry, "industry"),
  };
}

export function normalizeCreateUser(body: CreateUserRequest): CreateUserRequest {
  return {
    orgId: requiredText(body.orgId, "orgId"),
    fullName: requiredText(body.fullName, "fullName"),
    email: requiredText(body.email, "email"),
    role: requiredText(body.role, "role"),
    timezone: requiredText(body.timezone, "timezone"),
  };
}

export function normalizeCreateProject(body: CreateProjectRequest): CreateProjectRequest {
  return {
    orgId: requiredText(body.orgId, "orgId"),
    key: requiredText(body.key, "key"),
    name: requiredText(body.name, "name"),
    status: requiredText(body.status, "status"),
    ownerUserId: requiredText(body.ownerUserId, "ownerUserId"),
    dueDate:
      typeof body.dueDate === "string"
        ? body.dueDate.trim()
        : body.dueDate === null
          ? null
          : undefined,
  };
}

export function normalizeUpdateTask(body: UpdateTaskRequest): UpdateTaskRequest {
  return {
    title: optionalText(body.title),
    description: optionalText(body.description),
    status: optionalText(body.status),
    priority: optionalText(body.priority),
    assigneeUserId: nullableText(body.assigneeUserId),
    storyPoints: nullableInteger(body.storyPoints),
    dueDate:
      typeof body.dueDate === "string"
        ? body.dueDate
        : body.dueDate === null
          ? null
          : undefined,
  };
}
