/**
 * File tools — upload/download/list/delete files via the REST API.
 */
import * as fs from 'node:fs'
import * as path from 'node:path'
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { z } from 'zod'
import type { AbracadabraMCPServer } from '../server.ts'

export function registerFileTools(mcp: McpServer, server: AbracadabraMCPServer) {
  mcp.tool(
    'list_uploads',
    'List file attachments for a document.',
    {
      docId: z.string().describe('Document ID.'),
    },
    async ({ docId }) => {
      server.setAutoStatus('reading', docId)
      server.setActiveToolCall({ name: 'list_uploads', target: docId })
      try {
        const uploads = await server.client.listUploads(docId)
        return {
          content: [{
            type: 'text',
            text: JSON.stringify(uploads, null, 2),
          }],
        }
      } catch (error: any) {
        return {
          content: [{ type: 'text', text: `Error listing uploads: ${error.message}` }],
          isError: true,
        }
      }
    }
  )

  mcp.tool(
    'upload_file',
    'Upload a local file to a document.',
    {
      docId: z.string().describe('Document ID to attach the file to.'),
      filePath: z.string().describe('Absolute path to the local file to upload.'),
      filename: z.string().optional().describe('Override filename (defaults to basename of filePath).'),
    },
    async ({ docId, filePath, filename }) => {
      server.setAutoStatus('uploading', docId)
      server.setActiveToolCall({ name: 'upload_file', target: path.basename(filePath) })
      try {
        const resolvedPath = path.resolve(filePath)
        const data = fs.readFileSync(resolvedPath)
        const name = filename ?? path.basename(resolvedPath)
        const blob = new Blob([data])
        const result = await server.client.upload(docId, blob, name)
        return {
          content: [{
            type: 'text',
            text: JSON.stringify(result, null, 2),
          }],
        }
      } catch (error: any) {
        return {
          content: [{ type: 'text', text: `Error uploading file: ${error.message}` }],
          isError: true,
        }
      }
    }
  )

  mcp.tool(
    'download_file',
    'Download a file attachment from a document to a local path.',
    {
      docId: z.string().describe('Document ID.'),
      uploadId: z.string().describe('Upload ID to download.'),
      saveTo: z.string().describe('Absolute local file path to save the download.'),
    },
    async ({ docId, uploadId, saveTo }) => {
      server.setAutoStatus('reading', docId)
      server.setActiveToolCall({ name: 'download_file', target: path.basename(saveTo) })
      try {
        const blob = await server.client.getUpload(docId, uploadId)
        const buffer = Buffer.from(await blob.arrayBuffer())
        const resolvedPath = path.resolve(saveTo)
        fs.writeFileSync(resolvedPath, buffer)
        return {
          content: [{ type: 'text', text: `Downloaded to ${resolvedPath} (${buffer.length} bytes)` }],
        }
      } catch (error: any) {
        return {
          content: [{ type: 'text', text: `Error downloading file: ${error.message}` }],
          isError: true,
        }
      }
    }
  )

  mcp.tool(
    'delete_file',
    'Delete a file attachment from a document.',
    {
      docId: z.string().describe('Document ID.'),
      uploadId: z.string().describe('Upload ID to delete.'),
    },
    async ({ docId, uploadId }) => {
      server.setAutoStatus('writing', docId)
      server.setActiveToolCall({ name: 'delete_file', target: uploadId })
      try {
        await server.client.deleteUpload(docId, uploadId)
        return { content: [{ type: 'text', text: `Deleted upload ${uploadId}` }] }
      } catch (error: any) {
        return {
          content: [{ type: 'text', text: `Error deleting file: ${error.message}` }],
          isError: true,
        }
      }
    }
  )
}
