import axios from 'axios'
import { t } from '@/shared/i18n'

// Use relative paths, proxy to backend via Vite

// Generic API call function - compatible with Jingrow's jingrow.call style
export const api = {
  call: async (method: string, args?: Record<string, any>): Promise<any> => {
    try {
      const response = await axios.post('/api/action/' + method, args || {})
      return response.data
    } catch (error: any) {
      throw new Error(error.response?.data?.message || error.message || 'API call failed')
    }
  }
}

export const deleteRecord = async (pagetype: string, name: string): Promise<{ success: boolean; message?: string }> => {
  try {
    await api.call('jingrow.client.delete', {
      pagetype: pagetype,
      name: name
    })
    
    return { 
      success: true,
      message: t('Deleted successfully')
    }
  } catch (error: any) {
    return { success: false, message: error.response?.data?.message || error.message || t('Deletion failed') }
  }
}

export const deleteRecords = async (pagetype: string, names: string[]): Promise<{ success: boolean; message?: string }> => {
  if (!names || names.length === 0) {
    return { success: false, message: t('No records provided for deletion') }
  }
  
  let succeeded = 0
  let failed = 0
  
  // Call jingrow.client.delete RPC interface directly, avoid REST API wrapper
  for (const name of names) {
    try {
      await api.call('jingrow.client.delete', {
        pagetype: pagetype,
        name: name
      })
      succeeded++
    } catch {
      failed++
    }
  }
  
  if (failed === 0) {
    return { success: true, message: t('Successfully deleted {count} records', { count: succeeded }) }
  } else if (succeeded > 0) {
    return { success: true, message: t('Deleted {succeeded} of {total} records, {failed} failed', { succeeded, total: names.length, failed }) }
  } else {
    return { success: false, message: t('Deletion failed') }
  }
}

// Generic function to create a record
export const createRecord = async (pagetype: string, data: Record<string, any>): Promise<{ success: boolean; data?: any; message?: string }> => {
  try {
    const response = await axios.post(
      `/api/data/${pagetype}`, data)

    const message = response.data?.message
    return { success: true, data: message || response.data, message: 'Created successfully' }
  } catch (error: any) {
    return { success: false, message: error.response?.data?.message || error.message || t('Failed to create record') }
  }
}

// Generic function to update a record
export const updateRecord = async (pagetype: string, name: string, data: Record<string, any>): Promise<{ success: boolean; data?: any; message?: string }> => {
  try {
    const response = await axios.put(
      `/api/data/${pagetype}/${name}`, data)

    const message = response.data?.message
    return { success: true, data: message || response.data, message: 'Updated successfully' }
  } catch (error: any) {
    return { success: false, message: error.response?.data?.message || error.message || t('Failed to update record') }
  }
}

// Generic function to get a record
export const getRecord = async (pagetype: string, name: string): Promise<{ success: boolean; data?: any; message?: string }> => {
  try {
    const response = await axios.get(
      `/api/data/${pagetype}/${name}`)
    return { success: true, data: response.data.data }
  } catch (error: any) {
    return { success: false, message: error.response?.data?.message || error.message || t('Failed to get record') }
  }
}

// Get record with __onload data (calls document's onload method)
// Used for scenarios needing __onload data, like User pagetype's all_modules
export const getRecordWithOnload = async (pagetype: string, name: string): Promise<{ success: boolean; data?: any; message?: string }> => {
  try {
    // Use getpage RPC method, which calls onload method and returns __onload data
    const result = await api.call('jingrow.desk.form.load.getpage', { pagetype, name })
    
    // Compatible with two response formats:
    // SaaS returns { pgs: [pg], pageinfo: {...} } directly
    // jlocal returns { message: { pgs: [pg], pageinfo: {...} } }
    const docData = result.pgs ? result : (result.message || {})
    const pg = docData.pgs?.[0]
    if (pg) {
      return { success: true, data: pg }
    } else {
      return { success: false, message: t('Document not found') }
    }
  } catch (error: any) {
    return { success: false, message: error.message || t('Failed to get record') }
  }
}

// Get PageType metadata - via REST API v2
export const getPageTypeMeta = async (pagetype: string): Promise<{ success: boolean; data?: any; message?: string }> => {
  try {
    const response = await axios.get(
      `/api/v2/pagetype/${pagetype}/meta`
    )

    const meta = response.data?.data
    if (meta) {
      return { success: true, data: meta }
    } else {
      return { success: false, message: t('Failed to get metadata') }
    }
  } catch (error: any) {
    return { 
      success: false, 
      message: error.response?.data?.message || error.message || t('Failed to get metadata') 
    }
  }
}

// Get quick entry fields for a PageType
export const getQuickEntryFields = async (pagetype: string): Promise<{ success: boolean; data?: any[]; message?: string }> => {
  try {
    const result = await api.call('jingrow.client.get_quick_entry_fields', { pagetype })
    return { success: true, data: result.message || [] }
  } catch (error: any) {
    return { success: false, data: [], message: error.message || t('Failed to get quick entry fields') }
  }
}

// Get record attachments list
export const getRecordAttachments = async (pagetype: string, name: string): Promise<{ success: boolean; data?: any[]; message?: string }> => {
  try {
    const response = await axios.get(
      `/api/data/File`,
      {
        params: { 
          filters: JSON.stringify({
            attached_to_pagetype: pagetype,
            attached_to_name: name
          }),
          fields: JSON.stringify(['name', 'file_name', 'file_url', 'is_private'])
        }
      }
    )
    return { success: true, data: response.data.data || [] }
  } catch (error: any) {
    return { success: false, message: error.response?.data?.message || error.message || t('Failed to get attachments') }
  }
}

// Upload attachment
export const uploadAttachment = async (
  file: File, 
  pagetype: string, 
  pagename: string, 
  isPrivate: boolean = false
): Promise<{ success: boolean; data?: any; message?: string }> => {
  try {
    const formData = new FormData()
    formData.append('file', file)
    formData.append('file_name', file.name)
    formData.append('pagetype', pagetype)
    formData.append('pagename', pagename)
    formData.append('is_private', isPrivate ? '1' : '0')
    formData.append('folder', 'Home')
    
    const response = await axios.post(
      '/api/action/upload_file',
      formData,
      {
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      }
    )
    
    return { success: true, data: response.data.message }
  } catch (error: any) {
    return { 
      success: false, 
      message: error.response?.data?.message || error.message || t('Failed to upload attachment') 
    }
  }
}

// Delete attachment
export const deleteAttachment = async (attachmentName: string): Promise<{ success: boolean; message?: string }> => {
  try {
    await axios.delete(
      `/api/data/File/${attachmentName}`)
    return { success: true, message: t('Attachment deleted successfully') }
  } catch (error: any) {
    return { success: false, message: error.response?.data?.message || error.message || t('Failed to delete attachment') }
  }
}

// Get Workspace config
export const getWorkspace = async (name: string): Promise<{ success: boolean; data?: any; message?: string }> => {
  return getRecord('Workspace', name)
}

// Save Workspace layout
export const saveWorkspaceLayout = async (
  title: string, 
  isPublic: boolean, 
  content: any[],
  newWidgets: any = {}
): Promise<{ success: boolean; data?: any; message?: string }> => {
  try {
    const response = await axios.post(
      '/api/action/jingrow.desk.pagetype.workspace.workspace.save_page',
      {
        title,
        public: isPublic ? 1 : 0,
        new_widgets: JSON.stringify(newWidgets),
        blocks: JSON.stringify(content)
      }
    )
    return { success: true, data: response.data?.message, message: 'Workspace saved successfully' }
  } catch (error: any) {
    console.error('Save workspace error:', error.response?.data)
    return { 
      success: false, 
      message: error.response?.data?.exception || error.response?.data?.message || error.message || 'Failed to save workspace' 
    }
  }
}

// Generic function to get record count
export const getCount = async (pagetype: string): Promise<{ success: boolean; count?: number; message?: string }> => {
  try {
    const response = await axios.get(
      '/api/action/jingrow.client.get_count',
      {
        params: {
          pagetype: pagetype
        }
      }
    )
    
    const count = response.data?.message
    return { success: true, count: count || 0 }
  } catch (error: any) {
    return { 
      success: false, 
      count: 0,
      message: error.response?.data?.message || error.message || t('Failed to get record count') 
    }
  }
}

// Get Local Job count - via dedicated endpoint
export const getLocalJobCount = async (): Promise<{ success: boolean; count?: number; message?: string }> => {
  try {
    const response = await axios.get(
      `/api/action/jingrow.core.pagetype.local_job.local_job.get_local_job_count`)
    
    const count = response.data?.count || 0
    return { 
      success: true, 
      count: count,
      message: t('Local job count retrieved successfully')
    }
  } catch (error: any) {
    return { 
      success: false, 
      count: 0,
      message: error.response?.data?.detail || error.response?.data?.message || error.message || t('Failed to get local job count') 
    }
  }
}

// Generic function to get records list
export const getRecords = async (pagetype: string, filters: any[] = [], fields: string[] = [], orderBy: string = 'modified desc', limitStart: number = 0, limitPageLength: number = 20): Promise<{ success: boolean; data?: any[]; total?: number; message?: string }> => {
  try {
    const response = await axios.get(
      `/api/data/${pagetype}`,
      {
        params: {
          fields: JSON.stringify(fields),
          filters: JSON.stringify(filters),
          order_by: orderBy,
          limit_start: limitStart,
          limit_page_length: limitPageLength
        }
      }
    )
    
    const data = response.data
    if (data?.error) {
      const errorMsg = typeof data.error === 'object' ? JSON.stringify(data.error) : data.error
      throw new Error(errorMsg)
    }

    return {
      success: true,
      data: data?.data || [],
      total: data?.total || data?.data?.length || 0
    }
  } catch (error: any) {
    return { 
      success: false, 
      message: error.response?.data?.message || error.message || t('Failed to get records list') 
    }
  }
}

// Upload file to Jingrow server
export const uploadFileToJingrow = async (
  file: File, 
  attachedToPagetype?: string, 
  attachedToName?: string, 
  attachedToField?: string,
  folder?: string
): Promise<{ success: boolean; file_url?: string; file_name?: string; local_path?: string; error?: string }> => {
  try {
    const formData = new FormData()
    formData.append('file', file)
    formData.append('file_name', file.name)
    formData.append('is_private', '0')
    
    if (folder) {
      formData.append('folder', folder)
    }
    
    if (attachedToPagetype && attachedToName) {
      formData.append('pagetype', attachedToPagetype)
      formData.append('pagename', attachedToName)
    }
    
    if (attachedToField) {
      formData.append('fieldname', attachedToField)
    }

    const response = await axios.post(
      '/api/action/upload_file',
      formData,
      {
        headers: {
          'Content-Type': 'multipart/form-data'
        },
        timeout: 30000
      }
    )

    if (response.status === 200) {
      const result = response.data
      
      if (result.message) {
        return {
          success: true,
          file_url: result.message.file_url,
          file_name: result.message.file_name
        }
      } else {
        return { success: false, error: t('Invalid API response format') }
      }
    } else {
      return { success: false, error: `API request failed (HTTP ${response.status}): ${response.statusText}` }
    }
  } catch (error: any) {
    return { 
      success: false, 
      error: error.response?.data?.message || error.message || t('Failed to upload file') 
    }
  }
}

// Duplicate a document via backend REST API (aligns with old frontend jingrow.model.copy_pg)
// Backend endpoint: GET /api/v2/document/{pagetype}/{name}/copy
// Returns a clean copy with no_copy fields cleared, system fields cleared.
// Does NOT save the copy — caller should navigate to new record page with the copy data pre-filled,
// letting the user review and manually save (matching old frontend behavior).
export const duplicateRecord = async (
  pagetype: string,
  name: string
): Promise<{ success: boolean; data?: any; message?: string }> => {
  try {
    const response = await axios.get(
      `/api/v2/document/${encodeURIComponent(pagetype)}/${encodeURIComponent(name)}/copy`
    )

    const copyData = response.data?.data
    if (!copyData) {
      return { success: false, message: t('Failed to duplicate record') }
    }

    return { success: true, data: copyData }
  } catch (error: any) {
    return {
      success: false,
      message: error.response?.data?.message || error.message || t('Failed to duplicate record')
    }
  }
}

// Rename a document via backend API (aligns with old frontend jingrow.rename_pg)
// Uses jingrow.model.rename_pg.update_document_title for rename + title update
export const renameRecord = async (
  pagetype: string,
  pagename: string,
  newName: string,
  merge: boolean = false
): Promise<{ success: boolean; data?: string; message?: string }> => {
  try {
    const result = await api.call('jingrow.model.rename_pg.update_document_title', {
      pagetype,
      pagename,
      name: newName,
      merge,
      enqueue: false
    })
    // Align with old frontend's xcall which resolves r.message (unwrapped string).
    // api.call returns response.data which is { message: "xxx" } for RPC calls.
    const renamedName = typeof result === 'string' ? result : (result?.message || newName)
    return { success: true, data: renamedName, message: t('Document renamed successfully') }
  } catch (error: any) {
    return {
      success: false,
      message: error?.response?.data?.message || error?.message || t('Failed to rename document')
    }
  }
}

// Search records (supports translation search) - uses backend search_widget API
// For PageTypes marked with translated_pagetype, backend automatically handles translation search
export const searchWidget = async (
  pagetype: string,
  txt: string,
  options?: {
    searchfield?: string
    page_length?: number
    start?: number
    filters?: any[] | Record<string, any>
    reference_pagetype?: string
    ignore_user_permissions?: boolean
  }
): Promise<{ success: boolean; data?: any[]; message?: string }> => {
  try {
    const params: Record<string, any> = {
      pagetype,
      txt: txt || '',
      page_length: options?.page_length || 20,
      start: options?.start || 0,
      as_dict: 1  // Return dict format instead of array format
    }
    
    if (options?.searchfield) {
      params.searchfield = options.searchfield
    }
    
    if (options?.filters) {
      params.filters = typeof options.filters === 'string' 
        ? options.filters 
        : JSON.stringify(options.filters)
    }
    
    if (options?.reference_pagetype) {
      params.reference_pagetype = options.reference_pagetype
    }
    
    if (options?.ignore_user_permissions !== undefined) {
      params.ignore_user_permissions = options.ignore_user_permissions ? 1 : 0
    }
    
    const response = await axios.get('/api/action/jingrow.desk.search.search_widget', {
      params
    })
    
    return {
      success: true,
      data: response.data?.message || []
    }
  } catch (error: any) {
    return {
      success: false,
      message: error.response?.data?.message || error.message || t('Search failed')
    }
  }
}

