import api from "./api.js";
import { SWI_DOCUMENT_STATUS } from "../constants/swiDocumentStatus.js";

/** DB may expose `Location_name` (legacy) or `location_name`. */
function normalizeLocationRow(row) {
  if (row == null || typeof row !== "object") return row;
  const location_name =
    row.location_name ??
    row.Location_name ??
    row.locationName ??
    row.name ??
    "";
  const location_id = row.location_id ?? row.locationId ?? row.id;
  return { ...row, location_id, location_name };
}

function asRecordList(payload) {
  if (Array.isArray(payload)) return payload;
  if (Array.isArray(payload?.data)) return payload.data;
  return [];
}

export async function fetchLookupTables() {
  const [statuses, jobAreas, locations, departments] = await Promise.all([
    api.get("/swi_document_status"),
    api.get("/swi_job_area"),
    api.get("/locations"),
    api.get("/departments"),
  ]);
  return {
    statuses: statuses.data,
    jobAreas: jobAreas.data,
    locations: asRecordList(locations.data).map(normalizeLocationRow),
    departments: asRecordList(departments.data),
  };
}

export async function fetchDocuments() {
  const { data } = await api.get("/swi_document");
  return data;
}

export async function fetchUsers() {
  const { data } = await api.get("/users");
  return data;
}

/** PUT body for assign-document page (assigned user only). */
export function buildAssignDocumentPayload(assignedToUserId, { existingRow } = {}) {
  const payload = {};
  if (assignedToUserId) {
    payload.assigned_to_user_id = Number(assignedToUserId);
    if (!existingRow?.assigned_at) {
      payload.assigned_at = new Date()
        .toISOString()
        .slice(0, 19)
        .replace("T", " ");
    }
    payload.document_status_id = SWI_DOCUMENT_STATUS.ASSIGNED;
  } else {
    payload.assigned_to_user_id = null;
  }
  return payload;
}

export async function getDocument(documentId, documentNumber) {
  const { data } = await api.get(
    `/swi_document/${documentId}/${documentNumber}`
  );
  return data;
}

/**
 * @param {Record<string, unknown>} payload — maps to `swi_document` columns
 */
export async function createDocument(payload) {
  const { data } = await api.post("/swi_document", payload);
  return data;
}

export async function updateDocument(documentId, documentNumber, payload) {
  const { data } = await api.put(
    `/swi_document/${documentId}/${documentNumber}`,
    payload
  );
  return data;
}

/**
 * Suggest next PK pair.
 * - New document family: new document_id, document_number = 1
 * - New revision: same document_id, document_number + 1
 */
export function nextDocumentIds(existing, documentIdHint = null) {
  if (documentIdHint != null && documentIdHint !== "") {
    const id = Number(documentIdHint);
    let maxNum = 0;
    for (const row of existing) {
      if (Number(row.document_id) === id) {
        maxNum = Math.max(maxNum, Number(row.document_number) || 0);
      }
    }
    return { document_id: id, document_number: maxNum + 1 || 1 };
  }

  let maxDocId = 0;
  for (const row of existing) {
    maxDocId = Math.max(maxDocId, Number(row.document_id) || 0);
  }
  return { document_id: maxDocId + 1, document_number: 1 };
}

/** Build POST body aligned with swi_document table. */
export function buildCreateDocumentPayload(form) {
  const payload = {
    document_id: Number(form.document_id),
    document_number: Number(form.document_number),
    document_name: String(form.document_name || "").trim(),
    document_status_id: SWI_DOCUMENT_STATUS.OPENED,
  };
  if (form.location_id) payload.location_id = Number(form.location_id);
  if (form.department_id) payload.department_id = Number(form.department_id);
  if (form.job_area_id) payload.job_area_id = Number(form.job_area_id);
  if (form.process_name?.trim()) payload.process_name = form.process_name.trim();
  if (form.page_count !== "" && form.page_count != null) {
    payload.page_count = Number(form.page_count);
  }
  if (form.previous_document_id) {
    payload.previous_document_id = Number(form.previous_document_id);
  }
  if (form.assigned_to_user_id) {
    payload.assigned_to_user_id = Number(form.assigned_to_user_id);
    payload.assigned_at = form.assigned_at || new Date().toISOString().slice(0, 19).replace("T", " ");
    payload.document_status_id = SWI_DOCUMENT_STATUS.ASSIGNED;
  }
  if (form.issued_at) {
    payload.issued_at = form.issued_at;
  }

  return payload;
}

/** Build PUT body (assignment / updates). */
export function buildUpdateDocumentPayload(form, { existingRow } = {}) {
  const payload = {};

  if (form.document_name != null) {
    payload.document_name = String(form.document_name).trim();
  }
  if (form.document_status_id) {
    payload.document_status_id = Number(form.document_status_id);
  } else if (form.document_status_id === "") {
    payload.document_status_id = null;
  }

  if (form.assigned_to_user_id) {
    payload.assigned_to_user_id = Number(form.assigned_to_user_id);
    if (!existingRow?.assigned_at) {
      payload.assigned_at =
        form.assigned_at ||
        new Date().toISOString().slice(0, 19).replace("T", " ");
    }
  } else if (form.assigned_to_user_id === "") {
    payload.assigned_to_user_id = null;
  }

  if (form.location_id) payload.location_id = Number(form.location_id);
  if (form.department_id) payload.department_id = Number(form.department_id);
  if (form.job_area_id) payload.job_area_id = Number(form.job_area_id);
  if (form.process_name != null) {
    payload.process_name = form.process_name.trim() || null;
  }
  if (form.page_count !== "" && form.page_count != null) {
    payload.page_count = Number(form.page_count);
  }
  if (form.previous_document_id) {
    payload.previous_document_id = Number(form.previous_document_id);
  }
  if (form.completed_at) {
    payload.completed_at = form.completed_at;
  }

  return payload;
}

export async function fetchMyAssignments() {
  const { data } = await api.get("/me/assignments");
  return data;
}

export async function fetchMyProfile() {
  const { data } = await api.get("/me/profile");
  return data;
}

export async function fetchMyLocationDocuments() {
  const { data } = await api.get("/me/location/documents");
  return data;
}

export async function fetchAssignmentForm(documentId, documentNumber, pageNum) {
  const { data } = await api.get(
    `/me/assignments/${documentId}/${documentNumber}/form`,
    {
      params:
        pageNum != null && pageNum !== ""
          ? { page_num: Number(pageNum) }
          : undefined,
    }
  );
  return data;
}

export async function fetchAssignmentDocumentPages(documentId, documentNumber) {
  const { data } = await api.get(
    `/me/assignments/${documentId}/${documentNumber}/pages`
  );
  return data;
}

export async function createAssignmentPage(documentId, documentNumber) {
  const { data } = await api.post(
    `/me/assignments/${documentId}/${documentNumber}/pages`
  );
  return data;
}

export async function copyAssignmentPage(
  targetDocumentId,
  targetDocumentNumber,
  sourcePageId
) {
  const { data } = await api.post(
    `/me/assignments/${targetDocumentId}/${targetDocumentNumber}/pages/copy`,
    { source_page_id: Number(sourcePageId) }
  );
  return data;
}

export async function deleteAssignmentPage(
  documentId,
  documentNumber,
  pageId
) {
  const { data } = await api.delete(
    `/me/assignments/${documentId}/${documentNumber}/pages/${Number(pageId)}`
  );
  return data;
}

export async function reorderAssignmentPages(documentId, documentNumber, pages) {
  const { data } = await api.put(
    `/me/assignments/${documentId}/${documentNumber}/pages/order`,
    { pages }
  );
  return data;
}

export async function saveAssignmentForm(
  documentId,
  documentNumber,
  form,
  { markComplete = false } = {}
) {
  const { data } = await api.put(
    `/me/assignments/${documentId}/${documentNumber}/form`,
    { form, mark_complete: markComplete }
  );
  return data;
}

export async function startAssignmentWork(documentId, documentNumber) {
  const { data } = await api.post(
    `/me/assignments/${documentId}/${documentNumber}/start`
  );
  return data;
}
