/**
 * Trustee API
 * 
 * API-Funktionen für das Trustee-Feature.
 * Alle Endpunkte erfordern eine instanceId für den Feature-Instanz-Kontext.
 * 
 * URL-Struktur: /api/trustee/{instanceId}/{entity}
 */

import { ApiRequestOptions } from '../hooks/useApi';

// ============================================================================
// TYPES & INTERFACES
// ============================================================================

export interface TrusteeOrganisation {
  id: string;
  label: string;
  enabled: boolean;
  mandateId?: string;
  _createdAt?: number;
  _modifiedAt?: number;
  _createdBy?: string;
  _modifiedBy?: string;
  [key: string]: any;
}

export interface TrusteeRole {
  id: string;
  desc: string;
  mandateId?: string;
  _createdAt?: number;
  _modifiedAt?: number;
  _createdBy?: string;
  _modifiedBy?: string;
  [key: string]: any;
}

export interface TrusteeAccess {
  id: string;
  organisationId: string;
  roleId: string;
  userId: string;
  contractId?: string | null;
  mandateId?: string;
  _createdAt?: number;
  _modifiedAt?: number;
  _createdBy?: string;
  _modifiedBy?: string;
  [key: string]: any;
}

export interface TrusteeContract {
  id: string;
  organisationId: string;
  label: string;
  enabled: boolean;
  mandateId?: string;
  _createdAt?: number;
  _modifiedAt?: number;
  _createdBy?: string;
  _modifiedBy?: string;
  [key: string]: any;
}

export interface TrusteeDocument {
  id: string;
  organisationId: string;
  contractId: string;
  documentName: string;
  documentMimeType: string;
  documentData?: any;
  mandateId?: string;
  _createdAt?: number;
  _modifiedAt?: number;
  _createdBy?: string;
  _modifiedBy?: string;
  [key: string]: any;
}

export interface TrusteePosition {
  id: string;
  organisationId: string;
  contractId: string;
  valuta?: string;
  transactionDateTime?: number;
  company: string;
  desc: string;
  tags: string;
  bookingCurrency: string;
  bookingAmount: number;
  originalCurrency: string;
  originalAmount: number;
  vatPercentage: number;
  vatAmount: number;
  mandateId?: string;
  _createdAt?: number;
  _modifiedAt?: number;
  _createdBy?: string;
  _modifiedBy?: string;
  [key: string]: any;
}

export interface TrusteePositionDocument {
  id: string;
  organisationId: string;
  contractId: string;
  documentId: string;
  positionId: string;
  mandateId?: string;
  _createdAt?: number;
  _modifiedAt?: number;
  _createdBy?: string;
  _modifiedBy?: string;
  [key: string]: any;
}

export interface PaginationParams {
  page?: number;
  pageSize?: number;
  sort?: Array<{ field: string; direction: 'asc' | 'desc' }>;
  filters?: Record<string, any>;
  search?: string;
}

export interface PaginatedResponse<T> {
  items: T[];
  pagination?: {
    currentPage: number;
    pageSize: number;
    totalItems: number;
    totalPages: number;
  };
}

export type ApiRequestFunction = (options: ApiRequestOptions<any>) => Promise<any>;

// ============================================================================
// HELPER FUNCTIONS
// ============================================================================

function _buildPaginationParams(params?: PaginationParams): Record<string, any> {
  const requestParams: any = {};
  
  if (params) {
    const paginationObj: any = {};
    
    if (params.page !== undefined) paginationObj.page = params.page;
    if (params.pageSize !== undefined) paginationObj.pageSize = params.pageSize;
    if (params.sort) paginationObj.sort = params.sort;
    if (params.filters) paginationObj.filters = params.filters;
    if (params.search) paginationObj.search = params.search;
    
    if (Object.keys(paginationObj).length > 0) {
      requestParams.pagination = JSON.stringify(paginationObj);
    }
  }
  
  return requestParams;
}

/**
 * Erstellt die Basis-URL für Trustee-Endpunkte
 */
function _getTrusteeBaseUrl(instanceId: string): string {
  return `/api/trustee/${instanceId}`;
}

// ============================================================================
// ORGANISATION API
// ============================================================================

export async function fetchOrganisations(
  request: ApiRequestFunction,
  instanceId: string,
  params?: PaginationParams
): Promise<PaginatedResponse<TrusteeOrganisation> | TrusteeOrganisation[]> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/organisations`,
    method: 'get',
    params: _buildPaginationParams(params)
  });
}

export async function fetchOrganisationById(
  request: ApiRequestFunction,
  instanceId: string,
  orgId: string
): Promise<TrusteeOrganisation | null> {
  try {
    return await request({
      url: `${_getTrusteeBaseUrl(instanceId)}/organisations/${orgId}`,
      method: 'get'
    });
  } catch (error: any) {
    console.error('Error fetching organisation by ID:', error);
    return null;
  }
}

export async function createOrganisation(
  request: ApiRequestFunction,
  instanceId: string,
  data: Partial<TrusteeOrganisation>
): Promise<TrusteeOrganisation> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/organisations`,
    method: 'post',
    data
  });
}

export async function updateOrganisation(
  request: ApiRequestFunction,
  instanceId: string,
  orgId: string,
  data: Partial<TrusteeOrganisation>
): Promise<TrusteeOrganisation> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/organisations/${orgId}`,
    method: 'put',
    data
  });
}

export async function deleteOrganisation(
  request: ApiRequestFunction,
  instanceId: string,
  orgId: string
): Promise<void> {
  await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/organisations/${orgId}`,
    method: 'delete'
  });
}

// ============================================================================
// ROLE API
// ============================================================================

export async function fetchRoles(
  request: ApiRequestFunction,
  instanceId: string,
  params?: PaginationParams
): Promise<PaginatedResponse<TrusteeRole> | TrusteeRole[]> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/roles`,
    method: 'get',
    params: _buildPaginationParams(params)
  });
}

export async function fetchRoleById(
  request: ApiRequestFunction,
  instanceId: string,
  roleId: string
): Promise<TrusteeRole | null> {
  try {
    return await request({
      url: `${_getTrusteeBaseUrl(instanceId)}/roles/${roleId}`,
      method: 'get'
    });
  } catch (error: any) {
    console.error('Error fetching role by ID:', error);
    return null;
  }
}

export async function createRole(
  request: ApiRequestFunction,
  instanceId: string,
  data: Partial<TrusteeRole>
): Promise<TrusteeRole> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/roles`,
    method: 'post',
    data
  });
}

export async function updateRole(
  request: ApiRequestFunction,
  instanceId: string,
  roleId: string,
  data: Partial<TrusteeRole>
): Promise<TrusteeRole> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/roles/${roleId}`,
    method: 'put',
    data
  });
}

export async function deleteRole(
  request: ApiRequestFunction,
  instanceId: string,
  roleId: string
): Promise<void> {
  await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/roles/${roleId}`,
    method: 'delete'
  });
}

// ============================================================================
// ACCESS API
// ============================================================================

export async function fetchAccess(
  request: ApiRequestFunction,
  instanceId: string,
  params?: PaginationParams
): Promise<PaginatedResponse<TrusteeAccess> | TrusteeAccess[]> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/access`,
    method: 'get',
    params: _buildPaginationParams(params)
  });
}

export async function fetchAccessById(
  request: ApiRequestFunction,
  instanceId: string,
  accessId: string
): Promise<TrusteeAccess | null> {
  try {
    return await request({
      url: `${_getTrusteeBaseUrl(instanceId)}/access/${accessId}`,
      method: 'get'
    });
  } catch (error: any) {
    console.error('Error fetching access by ID:', error);
    return null;
  }
}

export async function fetchAccessByOrganisation(
  request: ApiRequestFunction,
  instanceId: string,
  orgId: string
): Promise<TrusteeAccess[]> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/access/organisation/${orgId}`,
    method: 'get'
  });
}

export async function fetchAccessByUser(
  request: ApiRequestFunction,
  instanceId: string,
  userId: string
): Promise<TrusteeAccess[]> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/access/user/${userId}`,
    method: 'get'
  });
}

export async function createAccess(
  request: ApiRequestFunction,
  instanceId: string,
  data: Partial<TrusteeAccess>
): Promise<TrusteeAccess> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/access`,
    method: 'post',
    data
  });
}

export async function updateAccess(
  request: ApiRequestFunction,
  instanceId: string,
  accessId: string,
  data: Partial<TrusteeAccess>
): Promise<TrusteeAccess> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/access/${accessId}`,
    method: 'put',
    data
  });
}

export async function deleteAccess(
  request: ApiRequestFunction,
  instanceId: string,
  accessId: string
): Promise<void> {
  await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/access/${accessId}`,
    method: 'delete'
  });
}

// ============================================================================
// CONTRACT API
// ============================================================================

export async function fetchContracts(
  request: ApiRequestFunction,
  instanceId: string,
  params?: PaginationParams
): Promise<PaginatedResponse<TrusteeContract> | TrusteeContract[]> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/contracts`,
    method: 'get',
    params: _buildPaginationParams(params)
  });
}

export async function fetchContractById(
  request: ApiRequestFunction,
  instanceId: string,
  contractId: string
): Promise<TrusteeContract | null> {
  try {
    return await request({
      url: `${_getTrusteeBaseUrl(instanceId)}/contracts/${contractId}`,
      method: 'get'
    });
  } catch (error: any) {
    console.error('Error fetching contract by ID:', error);
    return null;
  }
}

export async function fetchContractsByOrganisation(
  request: ApiRequestFunction,
  instanceId: string,
  orgId: string
): Promise<TrusteeContract[]> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/contracts/organisation/${orgId}`,
    method: 'get'
  });
}

export async function createContract(
  request: ApiRequestFunction,
  instanceId: string,
  data: Partial<TrusteeContract>
): Promise<TrusteeContract> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/contracts`,
    method: 'post',
    data
  });
}

export async function updateContract(
  request: ApiRequestFunction,
  instanceId: string,
  contractId: string,
  data: Partial<TrusteeContract>
): Promise<TrusteeContract> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/contracts/${contractId}`,
    method: 'put',
    data
  });
}

export async function deleteContract(
  request: ApiRequestFunction,
  instanceId: string,
  contractId: string
): Promise<void> {
  await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/contracts/${contractId}`,
    method: 'delete'
  });
}

// ============================================================================
// DOCUMENT API
// ============================================================================

export async function fetchDocuments(
  request: ApiRequestFunction,
  instanceId: string,
  params?: PaginationParams
): Promise<PaginatedResponse<TrusteeDocument> | TrusteeDocument[]> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/documents`,
    method: 'get',
    params: _buildPaginationParams(params)
  });
}

export async function fetchDocumentById(
  request: ApiRequestFunction,
  instanceId: string,
  documentId: string
): Promise<TrusteeDocument | null> {
  try {
    return await request({
      url: `${_getTrusteeBaseUrl(instanceId)}/documents/${documentId}`,
      method: 'get'
    });
  } catch (error: any) {
    console.error('Error fetching document by ID:', error);
    return null;
  }
}

export async function fetchDocumentsByContract(
  request: ApiRequestFunction,
  instanceId: string,
  contractId: string
): Promise<TrusteeDocument[]> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/documents/contract/${contractId}`,
    method: 'get'
  });
}

export async function createDocument(
  request: ApiRequestFunction,
  instanceId: string,
  data: Partial<TrusteeDocument>
): Promise<TrusteeDocument> {
  // If documentData is a File, convert to base64
  let processedData = { ...data };
  if (data.documentData instanceof File) {
    const file = data.documentData as File;
    const arrayBuffer = await file.arrayBuffer();
    const base64 = btoa(
      new Uint8Array(arrayBuffer).reduce((data, byte) => data + String.fromCharCode(byte), '')
    );
    processedData.documentData = base64 as any;
    // Auto-set MIME type from file if not provided
    if (!processedData.documentMimeType && file.type) {
      processedData.documentMimeType = file.type;
    }
    // Auto-set name from file if not provided
    if (!processedData.documentName && file.name) {
      processedData.documentName = file.name;
    }
  }
  
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/documents`,
    method: 'post',
    data: processedData
  });
}

export async function updateDocument(
  request: ApiRequestFunction,
  instanceId: string,
  documentId: string,
  data: Partial<TrusteeDocument>
): Promise<TrusteeDocument> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/documents/${documentId}`,
    method: 'put',
    data
  });
}

export async function deleteDocument(
  request: ApiRequestFunction,
  instanceId: string,
  documentId: string
): Promise<void> {
  await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/documents/${documentId}`,
    method: 'delete'
  });
}

// ============================================================================
// POSITION API
// ============================================================================

export async function fetchPositions(
  request: ApiRequestFunction,
  instanceId: string,
  params?: PaginationParams
): Promise<PaginatedResponse<TrusteePosition> | TrusteePosition[]> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/positions`,
    method: 'get',
    params: _buildPaginationParams(params)
  });
}

export async function fetchPositionById(
  request: ApiRequestFunction,
  instanceId: string,
  positionId: string
): Promise<TrusteePosition | null> {
  try {
    return await request({
      url: `${_getTrusteeBaseUrl(instanceId)}/positions/${positionId}`,
      method: 'get'
    });
  } catch (error: any) {
    console.error('Error fetching position by ID:', error);
    return null;
  }
}

export async function fetchPositionsByContract(
  request: ApiRequestFunction,
  instanceId: string,
  contractId: string
): Promise<TrusteePosition[]> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/positions/contract/${contractId}`,
    method: 'get'
  });
}

export async function fetchPositionsByOrganisation(
  request: ApiRequestFunction,
  instanceId: string,
  orgId: string
): Promise<TrusteePosition[]> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/positions/organisation/${orgId}`,
    method: 'get'
  });
}

export async function createPosition(
  request: ApiRequestFunction,
  instanceId: string,
  data: Partial<TrusteePosition>
): Promise<TrusteePosition> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/positions`,
    method: 'post',
    data
  });
}

export async function updatePosition(
  request: ApiRequestFunction,
  instanceId: string,
  positionId: string,
  data: Partial<TrusteePosition>
): Promise<TrusteePosition> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/positions/${positionId}`,
    method: 'put',
    data
  });
}

export async function deletePosition(
  request: ApiRequestFunction,
  instanceId: string,
  positionId: string
): Promise<void> {
  await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/positions/${positionId}`,
    method: 'delete'
  });
}

// ============================================================================
// POSITION-DOCUMENT API
// ============================================================================

export async function fetchPositionDocuments(
  request: ApiRequestFunction,
  instanceId: string,
  params?: PaginationParams
): Promise<PaginatedResponse<TrusteePositionDocument> | TrusteePositionDocument[]> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/position-documents`,
    method: 'get',
    params: _buildPaginationParams(params)
  });
}

export async function fetchPositionDocumentById(
  request: ApiRequestFunction,
  instanceId: string,
  linkId: string
): Promise<TrusteePositionDocument | null> {
  try {
    return await request({
      url: `${_getTrusteeBaseUrl(instanceId)}/position-documents/${linkId}`,
      method: 'get'
    });
  } catch (error: any) {
    console.error('Error fetching position-document link by ID:', error);
    return null;
  }
}

export async function fetchDocumentsForPosition(
  request: ApiRequestFunction,
  instanceId: string,
  positionId: string
): Promise<TrusteePositionDocument[]> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/position-documents/position/${positionId}`,
    method: 'get'
  });
}

export async function fetchPositionsForDocument(
  request: ApiRequestFunction,
  instanceId: string,
  documentId: string
): Promise<TrusteePositionDocument[]> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/position-documents/document/${documentId}`,
    method: 'get'
  });
}

export async function createPositionDocument(
  request: ApiRequestFunction,
  instanceId: string,
  data: Partial<TrusteePositionDocument>
): Promise<TrusteePositionDocument> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/position-documents`,
    method: 'post',
    data
  });
}

export async function updatePositionDocument(
  request: ApiRequestFunction,
  instanceId: string,
  linkId: string,
  data: Partial<TrusteePositionDocument>
): Promise<TrusteePositionDocument> {
  return await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/position-documents/${linkId}`,
    method: 'put',
    data
  });
}

export async function deletePositionDocument(
  request: ApiRequestFunction,
  instanceId: string,
  linkId: string
): Promise<void> {
  await request({
    url: `${_getTrusteeBaseUrl(instanceId)}/position-documents/${linkId}`,
    method: 'delete'
  });
}
