import { Hono } from 'hono';
import { db, dbGet, dbAll, media } from '../db/index.js';
import { eq } from 'drizzle-orm';
import { requireAuth } from '../lib/auth.js';
import { generateId, getNow } from '../lib/utils.js';
import { writeFile, mkdir, unlink } from 'fs/promises';
import { existsSync } from 'fs';
import { join, extname } from 'path';

const mediaRouter = new Hono();

const UPLOAD_DIR = './uploads';
const ALLOWED_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/avif'];
const MAX_FILE_SIZE =
  (Number(process.env.MEDIA_MAX_UPLOAD_MB || '10') || 10) * 1024 * 1024; // default 10MB

// Ensure upload directory exists
async function ensureUploadDir() {
  if (!existsSync(UPLOAD_DIR)) {
    await mkdir(UPLOAD_DIR, { recursive: true });
  }
}

// Upload image
mediaRouter.post('/upload', requireAuth(['admin', 'organizer']), async (c) => {
  try {
    const body = await c.req.parseBody();
    const file = body['file'] as File;
    
    if (!file) {
      return c.json({ error: 'No file provided' }, 400);
    }
    
    // Validate file type
    if (!ALLOWED_TYPES.includes(file.type)) {
      return c.json({ error: 'Invalid file type. Allowed: JPEG, PNG, GIF, WebP, AVIF' }, 400);
    }
    
    // Validate file size
    if (file.size > MAX_FILE_SIZE) {
      const mb = Math.round((MAX_FILE_SIZE / (1024 * 1024)) * 10) / 10;
      return c.json({ error: `File too large. Maximum size: ${mb}MB` }, 400);
    }
    
    await ensureUploadDir();
    
    // Generate unique filename
    const id = generateId();
    const ext = extname(file.name) || '.jpg';
    const filename = `${id}${ext}`;
    const filepath = join(UPLOAD_DIR, filename);
    
    // Write file
    const arrayBuffer = await file.arrayBuffer();
    await writeFile(filepath, Buffer.from(arrayBuffer));
    
    // Get related info from form data
    const relatedId = body['relatedId'] as string | undefined;
    const relatedType = body['relatedType'] as string | undefined;
    
    // Save to database
    const now = getNow();
    const mediaRecord = {
      id,
      fileUrl: `/uploads/${filename}`,
      type: 'image' as const,
      relatedId: relatedId || null,
      relatedType: relatedType || null,
      createdAt: now,
    };
    
    await (db as any).insert(media).values(mediaRecord);
    
    return c.json({ 
      media: mediaRecord,
      url: mediaRecord.fileUrl,
    }, 201);
  } catch (error) {
    console.error('Upload error:', error);
    return c.json({ error: 'Failed to upload file' }, 500);
  }
});

// Get media by ID
mediaRouter.get('/:id', async (c) => {
  const id = c.req.param('id');
  
  const mediaRecord = await dbGet<any>(
    (db as any).select().from(media).where(eq((media as any).id, id))
  );
  
  if (!mediaRecord) {
    return c.json({ error: 'Media not found' }, 404);
  }
  
  return c.json({ media: mediaRecord });
});

// Delete media
mediaRouter.delete('/:id', requireAuth(['admin', 'organizer']), async (c) => {
  const id = c.req.param('id');
  
  const mediaRecord = await dbGet<any>(
    (db as any).select().from(media).where(eq((media as any).id, id))
  );
  
  if (!mediaRecord) {
    return c.json({ error: 'Media not found' }, 404);
  }
  
  // Delete file from disk
  try {
    const filepath = join('.', mediaRecord.fileUrl);
    if (existsSync(filepath)) {
      await unlink(filepath);
    }
  } catch (error) {
    console.error('Failed to delete file:', error);
  }
  
  // Delete from database
  await (db as any).delete(media).where(eq((media as any).id, id));
  
  return c.json({ message: 'Media deleted successfully' });
});

// List media (admin)
mediaRouter.get('/', requireAuth(['admin', 'organizer']), async (c) => {
  const relatedType = c.req.query('relatedType');
  const relatedId = c.req.query('relatedId');
  
  let query = (db as any).select().from(media);
  
  if (relatedType) {
    query = query.where(eq((media as any).relatedType, relatedType));
  }
  if (relatedId) {
    query = query.where(eq((media as any).relatedId, relatedId));
  }
  
  const result = await dbAll(query);
  
  return c.json({ media: result });
});

export default mediaRouter;
