/**
 * Upload API for file uploads via proxy to MinIO
 * Supports both Web and Native platforms
 */
import { Platform } from "react-native"

const OSS_BASE_URL = "https://oss.upay01.com"

// Upload response type
export interface UploadResponse {
  code: number
  message: string
  data?: {
    filename: string
    originalName: string
    size: number
    mimetype: string
    url: string
  }
}

/**
 * Convert a URI to Blob (for Web platform)
 */
async function uriToBlob(uri: string): Promise<Blob> {
  const response = await fetch(uri)
  const blob = await response.blob()
  return blob
}

/**
 * Upload file on Web platform
 */
async function uploadFileWeb(
  uri: string,
  fileName: string,
  mimeType: string,
): Promise<{ kind: "ok"; url: string } | { kind: "error"; message: string }> {
  try {
    // Convert URI to Blob for Web
    const blob = await uriToBlob(uri)
    const file = new File([blob], fileName, { type: mimeType })

    const formData = new FormData()
    formData.append("file", file)

    const response = await fetch(`${OSS_BASE_URL}/api/proxy/upload`, {
      method: "POST",
      body: formData,
    })

    const data: UploadResponse = await response.json()

    if (response.ok && data.code === 200 && data.data?.url) {
      return { kind: "ok", url: data.data.url }
    } else {
      return { kind: "error", message: data.message || "Upload failed" }
    }
  } catch (e) {
    if (__DEV__ && e instanceof Error) {
      console.error(`Upload error: ${e.message}`)
    }
    return { kind: "error", message: "Upload failed" }
  }
}

/**
 * Upload file on Native platform (iOS/Android)
 */
function uploadFileNative(
  uri: string,
  fileName: string,
  mimeType: string,
): Promise<{ kind: "ok"; url: string } | { kind: "error"; message: string }> {
  return new Promise((resolve) => {
    try {
      const xhr = new XMLHttpRequest()

      xhr.onload = () => {
        if (__DEV__) {
          console.log("Upload response status:", xhr.status)
          console.log("Upload response body:", xhr.responseText)
        }
        if (xhr.status === 200) {
          try {
            const response: UploadResponse = JSON.parse(xhr.responseText)
            if (response.code === 200 && response.data?.url) {
              resolve({ kind: "ok", url: response.data.url })
            } else {
              resolve({ kind: "error", message: response.message || "Upload failed" })
            }
          } catch {
            resolve({ kind: "error", message: "Invalid response" })
          }
        } else {
          if (__DEV__) {
            console.log("Upload failed - Status:", xhr.status, "Response:", xhr.responseText)
          }
          resolve({ kind: "error", message: `Upload failed with status ${xhr.status}` })
        }
      }

      xhr.onerror = () => {
        resolve({ kind: "error", message: "Network error" })
      }

      xhr.ontimeout = () => {
        resolve({ kind: "error", message: "Upload timeout" })
      }

      xhr.open("POST", `${OSS_BASE_URL}/api/proxy/upload`)
      xhr.timeout = 60000

      // React Native specific FormData format
      const formData = new FormData()
      formData.append("file", {
        uri: uri,
        type: mimeType,
        name: fileName,
      } as any)

      xhr.send(formData)
    } catch (e) {
      if (__DEV__ && e instanceof Error) {
        console.error(`Upload error: ${e.message}`)
      }
      resolve({ kind: "error", message: "Upload failed" })
    }
  })
}

/**
 * Upload a file to OSS storage
 * Automatically handles Web vs Native platform differences
 * @param uri - Local file URI
 * @param fileName - File name
 * @param mimeType - MIME type of the file
 * @returns Upload result with URL or error
 */
export async function uploadFile(
  uri: string,
  fileName: string,
  mimeType: string,
): Promise<{ kind: "ok"; url: string } | { kind: "error"; message: string }> {
  if (Platform.OS === "web") {
    return uploadFileWeb(uri, fileName, mimeType)
  } else {
    return uploadFileNative(uri, fileName, mimeType)
  }
}
