/**
 * Image Upload API Endpoint
 * Agent 3: File Upload & Storage System
 *
 * POST /api/upload/image - Upload an image file
 */

import type { NextApiRequest, NextApiResponse } from 'next';
import { getUploadService } from '../../../lib/storage';
import type { FileCategory, UploadResult } from '../../../lib/storage/types';

// Disable body parser to handle multipart/form-data
export const config = {
  api: {
    bodyParser: false,
  },
};

interface UploadResponse {
  success: boolean;
  file?: {
    id: string;
    url: string;
    thumbnailUrl?: string;
    urls?: Record<string, string>;
    width?: number;
    height?: number;
    size: number;
    mimeType: string;
  };
  error?: string;
}

async function parseMultipartForm(
  req: NextApiRequest
): Promise<{ buffer: Buffer; filename: string; mimeType: string; fields: Record<string, string> }> {
  return new Promise((resolve, reject) => {
    const chunks: Buffer[] = [];
    let filename = 'upload';
    let mimeType = 'application/octet-stream';
    const fields: Record<string, string> = {};

    const contentType = req.headers['content-type'] || '';
    const boundary = contentType.split('boundary=')[1];

    if (!boundary) {
      reject(new Error('Missing multipart boundary'));
      return;
    }

    req.on('data', (chunk: Buffer) => {
      chunks.push(chunk);
    });

    req.on('end', () => {
      const buffer = Buffer.concat(chunks);
      const content = buffer.toString('binary');
      const parts = content.split(`--${boundary}`);

      for (const part of parts) {
        if (part.includes('Content-Disposition: form-data')) {
          const nameMatch = part.match(/name="([^"]+)"/);
          const filenameMatch = part.match(/filename="([^"]+)"/);

          if (filenameMatch) {
            // This is a file
            filename = filenameMatch[1];
            const contentTypeMatch = part.match(/Content-Type: ([^\r\n]+)/);
            if (contentTypeMatch) {
              mimeType = contentTypeMatch[1].trim();
            }

            // Extract file content (after double CRLF)
            const contentStart = part.indexOf('\r\n\r\n') + 4;
            const contentEnd = part.lastIndexOf('\r\n');
            if (contentStart > 4 && contentEnd > contentStart) {
              const fileContent = part.slice(contentStart, contentEnd);
              const fileBuffer = Buffer.from(fileContent, 'binary');
              resolve({ buffer: fileBuffer, filename, mimeType, fields });
              return;
            }
          } else if (nameMatch) {
            // This is a regular field
            const fieldName = nameMatch[1];
            const contentStart = part.indexOf('\r\n\r\n') + 4;
            const contentEnd = part.lastIndexOf('\r\n');
            if (contentStart > 4 && contentEnd > contentStart) {
              fields[fieldName] = part.slice(contentStart, contentEnd).trim();
            }
          }
        }
      }

      reject(new Error('No file found in request'));
    });

    req.on('error', reject);
  });
}

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse<UploadResponse>
) {
  if (req.method !== 'POST') {
    return res.status(405).json({ success: false, error: 'Method not allowed' });
  }

  try {
    const { buffer, filename, mimeType, fields } = await parseMultipartForm(req);

    const category = (fields.category as FileCategory) || 'plant-photo';
    const plantId = fields.plantId;
    const farmId = fields.farmId;
    const userId = fields.userId;

    const uploadService = getUploadService();
    const result = await uploadService.upload(buffer, filename, mimeType, {
      category,
      plantId,
      farmId,
      userId,
      generateThumbnails: true,
    });

    if (!result.success || !result.file) {
      return res.status(400).json({
        success: false,
        error: result.error || 'Upload failed',
      });
    }

    return res.status(200).json({
      success: true,
      file: {
        id: result.file.id,
        url: result.file.url,
        thumbnailUrl: result.file.thumbnailUrl,
        urls: result.file.urls,
        width: result.file.width,
        height: result.file.height,
        size: result.file.size,
        mimeType: result.file.mimeType,
      },
    });
  } catch (error) {
    console.error('Upload error:', error);
    return res.status(500).json({
      success: false,
      error: error instanceof Error ? error.message : 'Internal server error',
    });
  }
}
