import { Router, type Request, type Response } from 'express';
import multer from 'multer';
import { z } from 'zod';
import { CopyMeThatImportService } from '../services/CopyMeThatImportService.js';
import { getDatabaseSync } from '../db/database.js';

// Configure multer for file uploads (memory storage)
const upload = multer({
  storage: multer.memoryStorage(),
  limits: {
    fileSize: 50 * 1024 * 1024, // 50MB max per file
    files: 200, // Max 200 files at once
  },
  fileFilter: (req, file, cb) => {
    const allowedTypes = ['.html', '.txt'];
    const ext = file.originalname.toLowerCase().slice(file.originalname.lastIndexOf('.'));
    if (allowedTypes.includes(ext)) {
      cb(null, true);
    } else {
      cb(new Error(`Invalid file type: ${ext}. Only .html and .txt files are allowed.`));
    }
  },
});

const importOptionsSchema = z.object({
  skipDuplicates: z.boolean().optional().default(true),
  importImages: z.boolean().optional().default(false),
});

export function createImportLocalRoutes() {
  const router = Router();

  /**
   * POST /api/recipes/import/local
   * Import recipes from local CopyMeThat export files (.html or .txt)
   */
  router.post('/local', upload.array('files', 200), async (req: Request, res: Response) => {
    try {
      const files = req.files as Express.Multer.File[] | undefined;
      
      if (!files || files.length === 0) {
        res.status(400).json({
          success: false,
          data: null,
          error: 'No files uploaded. Please upload at least one .html or .txt file.',
        });
        return;
      }

      // Parse options from request body (sent as form data)
      const options = importOptionsSchema.parse({
        skipDuplicates: req.body.skipDuplicates === 'true' || req.body.skipDuplicates === true,
        importImages: req.body.importImages === 'true' || req.body.importImages === true,
      });

      const db = getDatabaseSync();
      const importService = new CopyMeThatImportService(db);

      // Separate HTML and TXT files
      const htmlFiles = files.filter(f => f.originalname.toLowerCase().endsWith('.html'));
      const txtFiles = files.filter(f => f.originalname.toLowerCase().endsWith('.txt'));

      let combinedResult = {
        success: true,
        imported: 0,
        skipped: 0,
        failed: 0,
        recipes: [] as any[],
        errors: [] as string[],
      };

      // Process HTML files (priority - richer data)
      if (htmlFiles.length > 0) {
        for (const file of htmlFiles) {
          const html = file.buffer.toString('utf-8');
          const result = await importService.importFromHtml(html, options);
          
          combinedResult.imported += result.imported;
          combinedResult.skipped += result.skipped;
          combinedResult.failed += result.failed;
          combinedResult.recipes.push(...result.recipes);
          combinedResult.errors.push(...result.errors);
          
          if (!result.success) {
            combinedResult.success = false;
          }
        }
      }

      // Process TXT files
      if (txtFiles.length > 0) {
        const txtContents = txtFiles.map(f => ({
          filename: f.originalname,
          content: f.buffer.toString('utf-8'),
        }));
        
        const result = await importService.importFromTxtFiles(txtContents, options);
        
        combinedResult.imported += result.imported;
        combinedResult.skipped += result.skipped;
        combinedResult.failed += result.failed;
        combinedResult.recipes.push(...result.recipes);
        combinedResult.errors.push(...result.errors);
        
        if (!result.success) {
          combinedResult.success = false;
        }
      }

      // Return summary
      res.json({
        success: combinedResult.success,
        data: {
          imported: combinedResult.imported,
          skipped: combinedResult.skipped,
          failed: combinedResult.failed,
          total: files.length,
          recipes: combinedResult.recipes.slice(0, 10), // Preview first 10 recipes
          errors: combinedResult.errors,
        },
        error: combinedResult.errors.length > 0 ? `${combinedResult.failed} recipes failed to import` : null,
      });

    } catch (error) {
      if (error instanceof z.ZodError) {
        res.status(400).json({
          success: false,
          data: null,
          error: error.errors[0]?.message ?? 'Invalid options',
        });
        return;
      }

      if (error instanceof Error) {
        res.status(500).json({
          success: false,
          data: null,
          error: error.message,
        });
        return;
      }

      res.status(500).json({
        success: false,
        data: null,
        error: 'Internal server error during import',
      });
    }
  });

  return router;
}
