import * as session from "./session.js";
import * as authApi from "./authApi.js";
import * as genericApi from "./genericApi.js";
import * as employeesApi from "./employeesApi.js";
import * as facilitiesApi from "./facilitiesApi.js";
import * as facilityContactsApi from "./facilityContactsApi.js";
import * as facilityQualificationRatesApi from "./facilityQualificationRatesApi.js";
import * as employeeFacilityDistancesApi from "./employeeFacilityDistancesApi.js";
import * as ordersApi from "./ordersApi.js";
import * as assignmentsApi from "./assignmentsApi.js";
import * as assignmentValidationSettingsApi from "./assignmentValidationSettingsApi.js";
import * as absencesApi from "./absencesApi.js";
import * as timeEntriesApi from "./timeEntriesApi.js";
import * as usersApi from "./usersApi.js";
import * as rolesApi from "./rolesApi.js";
import * as auditLogApi from "./auditLogApi.js";
import * as valueListsApi from "./valueListsApi.js";
import * as trashApi from "./trashApi.js";
import * as contractsApi from "./contractsApi.js";
import * as documentsApi from "./documentsApi.js";

// Ersetzt electron/preload.cjs' contextBridge.exposeInMainWorld('omsorg', {...}) - dieselbe
// Oberfläche als reines Browser-Objekt statt IPC-Bridge, damit keine der 76+ Aufrufstellen
// unter src/modules/** angefasst werden muss (siehe Plan "Electron -> Browser-SPA-Migration").
function withAuth(fn) {
  return (...args) => session.withAuthRetry(() => fn(session.getAccessToken(), ...args));
}

// Ersetzt main.cjs' documents:download-Handler (dort: dialog.showSaveDialog + fs.writeFileSync).
async function downloadDocumentAsFile(id, fileName) {
  const result = await session.withAuthRetry(() => documentsApi.downloadDocument(session.getAccessToken(), id));
  if (!result.ok) return result;
  const url = URL.createObjectURL(result.data.blob);
  const link = document.createElement("a");
  link.href = url;
  link.download = fileName;
  link.click();
  URL.revokeObjectURL(url);
  return { ok: true };
}

export function buildOmsorgApi() {
  return {
    auth: {
      login: async (username, password) => {
        const result = await authApi.login(username, password);
        if (!result.ok) {
          const error = result.status === 0 ? "network_error" : result.status === 429 ? "too_many_attempts" : "invalid_credentials";
          return { success: false, error };
        }
        session.applySession(result);
        const snapshot = session.getSessionSnapshot();
        return { success: true, user: snapshot.user, mustChangePassword: snapshot.mustChangePassword };
      },
      logout: async () => {
        try {
          await authApi.logout();
        } catch {
          /* best effort */
        }
        session.clearSession();
        return { success: true };
      },
      getSession: async () => {
        if (!session.getAccessToken()) {
          await session.bootstrapSession();
        }
        return session.getSessionSnapshot();
      },
      onSessionChanged: session.onSessionChanged,
      requestPasswordReset: async (username) => {
        const result = await authApi.requestPasswordReset(username);
        if (!result.ok) return { success: false, error: "network_error" };
        return { success: true, status: result.status };
      },
      verifyPasswordResetCode: async (username, pin) => {
        const result = await authApi.verifyPasswordResetCode(username, pin);
        if (!result.ok) return { success: false, error: result.error || "invalid_or_expired" };
        return { success: true, resetToken: result.resetToken };
      },
      resetPassword: async (resetToken, newPassword) => {
        const result = await authApi.resetPassword(resetToken, newPassword);
        if (!result.ok) {
          const error = result.status === 400 ? "password_too_short" : "invalid_or_expired";
          return { success: false, error, message: result.status === 400 && typeof result.data === "string" ? result.data : undefined };
        }
        return { success: true };
      },
      changePassword: async (currentPassword, newPassword) => {
        if (!session.getAccessToken()) return { success: false, error: "not_authenticated" };
        const result = await authApi.changePassword(session.getAccessToken(), currentPassword, newPassword);
        if (!result.ok) {
          const error = result.status === 401 ? "invalid_current_password" : result.status === 400 ? "password_too_short" : "unknown";
          return { success: false, error, message: result.status === 400 && typeof result.data === "string" ? result.data : undefined };
        }
        session.clearSession();
        return { success: true };
      },
      getPasswordPolicy: async () => {
        const result = await authApi.getPasswordPolicy();
        if (!result.ok) return { success: false };
        return { success: true, minLength: result.minLength };
      }
    },
    api: {
      get: (path) => session.withAuthRetry(() => genericApi.request("GET", path, session.getAccessToken())),
      post: (path, body) => session.withAuthRetry(() => genericApi.request("POST", path, session.getAccessToken(), body))
    },
    employees: {
      list: withAuth(employeesApi.listEmployees),
      create: withAuth(employeesApi.createEmployee),
      update: withAuth(employeesApi.updateEmployee),
      delete: withAuth(employeesApi.deleteEmployee)
    },
    facilities: {
      list: withAuth(facilitiesApi.listFacilities),
      create: withAuth(facilitiesApi.createFacility),
      update: withAuth(facilitiesApi.updateFacility),
      delete: withAuth(facilitiesApi.deleteFacility)
    },
    facilityContacts: {
      list: withAuth(facilityContactsApi.listFacilityContacts),
      create: withAuth(facilityContactsApi.createFacilityContact),
      update: withAuth(facilityContactsApi.updateFacilityContact),
      delete: withAuth(facilityContactsApi.deleteFacilityContact)
    },
    facilityQualificationRates: {
      list: withAuth(facilityQualificationRatesApi.listFacilityQualificationRates),
      create: withAuth(facilityQualificationRatesApi.createFacilityQualificationRate),
      update: withAuth(facilityQualificationRatesApi.updateFacilityQualificationRate),
      delete: withAuth(facilityQualificationRatesApi.deleteFacilityQualificationRate)
    },
    employeeFacilityDistances: {
      list: withAuth(employeeFacilityDistancesApi.listEmployeeFacilityDistances),
      create: withAuth(employeeFacilityDistancesApi.createEmployeeFacilityDistance),
      update: withAuth(employeeFacilityDistancesApi.updateEmployeeFacilityDistance),
      delete: withAuth(employeeFacilityDistancesApi.deleteEmployeeFacilityDistance)
    },
    orders: {
      list: withAuth(ordersApi.listOrders),
      create: withAuth(ordersApi.createOrder),
      get: withAuth(ordersApi.getOrder),
      update: withAuth(ordersApi.updateOrder),
      delete: withAuth(ordersApi.deleteOrder)
    },
    assignments: {
      list: withAuth(assignmentsApi.listAssignments),
      create: withAuth(assignmentsApi.createAssignment),
      get: withAuth(assignmentsApi.getAssignment),
      update: withAuth(assignmentsApi.updateAssignment),
      delete: withAuth(assignmentsApi.deleteAssignment),
      checkConflicts: withAuth(assignmentsApi.checkAssignmentConflicts)
    },
    assignmentValidationSettings: {
      get: withAuth(assignmentValidationSettingsApi.getAssignmentValidationSettings),
      update: withAuth(assignmentValidationSettingsApi.updateAssignmentValidationSettings)
    },
    absences: {
      list: withAuth(absencesApi.listAbsences),
      get: withAuth(absencesApi.getAbsence),
      update: withAuth(absencesApi.updateAbsence),
      decide: withAuth(absencesApi.decideAbsence),
      delete: withAuth(absencesApi.deleteAbsence)
    },
    timeEntries: {
      list: withAuth(timeEntriesApi.listTimeEntries),
      get: withAuth(timeEntriesApi.getTimeEntry),
      update: withAuth(timeEntriesApi.updateTimeEntry),
      submit: withAuth(timeEntriesApi.submitTimeEntry),
      decide: withAuth(timeEntriesApi.decideTimeEntry),
      delete: withAuth(timeEntriesApi.deleteTimeEntry)
    },
    users: {
      list: withAuth(usersApi.listUsers),
      create: withAuth(usersApi.createUser),
      listPermissionOverrides: withAuth(usersApi.listPermissionOverrides),
      addPermissionOverride: withAuth(usersApi.addPermissionOverride),
      deletePermissionOverride: withAuth(usersApi.deletePermissionOverride),
      update: withAuth(usersApi.updateUser),
      resetPassword: withAuth(usersApi.resetPassword)
    },
    roles: {
      list: withAuth(rolesApi.listRoles),
      get: withAuth(rolesApi.getRole),
      create: withAuth(rolesApi.createRole),
      updatePermissions: withAuth(rolesApi.updateRolePermissions),
      delete: withAuth(rolesApi.deleteRole)
    },
    auditLog: {
      list: withAuth(auditLogApi.listAuditLog)
    },
    valueLists: {
      list: withAuth(valueListsApi.listValueLists),
      listItems: withAuth(valueListsApi.listItems),
      createItem: withAuth(valueListsApi.createItem),
      updateItem: withAuth(valueListsApi.updateItem),
      deleteItem: withAuth(valueListsApi.deleteItem),
      getUsages: withAuth(valueListsApi.getUsages),
      listTransitions: withAuth(valueListsApi.listTransitions),
      replaceTransitions: withAuth(valueListsApi.replaceTransitions)
    },
    trash: {
      listEmployees: withAuth(trashApi.listDeletedEmployees),
      restoreEmployee: withAuth(trashApi.restoreEmployee),
      listFacilities: withAuth(trashApi.listDeletedFacilities),
      restoreFacility: withAuth(trashApi.restoreFacility),
      listContracts: withAuth(trashApi.listDeletedContracts),
      restoreContract: withAuth(trashApi.restoreContract),
      listOrders: withAuth(trashApi.listDeletedOrders),
      restoreOrder: withAuth(trashApi.restoreOrder),
      listFacilityContacts: withAuth(trashApi.listDeletedFacilityContacts),
      restoreFacilityContact: withAuth(trashApi.restoreFacilityContact),
      listFacilityQualificationRates: withAuth(trashApi.listDeletedFacilityQualificationRates),
      restoreFacilityQualificationRate: withAuth(trashApi.restoreFacilityQualificationRate),
      listEmployeeFacilityDistances: withAuth(trashApi.listDeletedEmployeeFacilityDistances),
      restoreEmployeeFacilityDistance: withAuth(trashApi.restoreEmployeeFacilityDistance),
      listAbsences: withAuth(trashApi.listDeletedAbsences),
      restoreAbsence: withAuth(trashApi.restoreAbsence),
      listTimeEntries: withAuth(trashApi.listDeletedTimeEntries),
      restoreTimeEntry: withAuth(trashApi.restoreTimeEntry),
      listAssignments: withAuth(trashApi.listDeletedAssignments),
      restoreAssignment: withAuth(trashApi.restoreAssignment)
    },
    contracts: {
      list: withAuth(contractsApi.listContracts),
      create: withAuth(contractsApi.createContract),
      update: withAuth(contractsApi.updateContract),
      delete: withAuth(contractsApi.deleteContract)
    },
    documents: {
      list: withAuth(documentsApi.listDocuments),
      upload: withAuth(documentsApi.uploadDocument),
      update: withAuth(documentsApi.updateDocument),
      delete: withAuth(documentsApi.deleteDocument),
      download: (id, fileName) => downloadDocumentAsFile(id, fileName),
      view: withAuth(documentsApi.downloadDocument)
    }
  };
}
