import path from 'path';
import fs from 'fs';
import express from 'express';
import multer from 'multer';
import {PrismaClient} from '../../generated/prisma';

const router = express.Router();
const prisma = new PrismaClient();

// Ensure uploads directory exists
const uploadsDir = path.resolve('uploads');
if (!fs.existsSync(uploadsDir)) {
  fs.mkdirSync(uploadsDir, {recursive: true});
}

// Configure multer for file uploads
const diskStorage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, uploadsDir);
  },
  filename: (req, file, cb) => {
    // Create unique filename with timestamp
    const uniqueName = `${Date.now()}-${file.originalname}`;
    cb(null, uniqueName);
  }
});

// File validation
const fileFilter = (req: any, file: Express.Multer.File, cb: multer.FileFilterCallback) => {
  // Accept only image files
  const allowedMimeTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'];
  if (allowedMimeTypes.includes(file.mimetype)) {
    cb(null, true);
  } else {
    cb(new Error('Invalid file type. Only JPEG, PNG, GIF, and WebP images are allowed.'));
  }
};

const upload = multer({
  storage: diskStorage,
  fileFilter: fileFilter,
  limits: {
    fileSize: 10 * 1024 * 1024 // 10MB limit
  }
});

// GET all artworks
router.get('/', async (req, res) => {
  try {
    const artworks = await prisma.artworks.findMany({
      select: {
        id: true,
        title: true,
        filename: true,
        mimetype: true,
        size: true,
        created_at: true,
        updated_at: true
      },
      orderBy: {
        created_at: 'desc'
      }
    });

    return res.status(200).json(artworks);
  } catch (error: any) {
    console.error(error.message);
    return res.status(500).json({status: 'error', message: 'Internal server error'});
  }
});

// GET single artwork metadata
router.get('/:id', async (req, res) => {
  const {id} = req.params;
  try {
    const artwork = await prisma.artworks.findUnique({
      where: {id},
      select: {
        id: true,
        title: true,
        filename: true,
        mimetype: true,
        size: true,
        created_at: true,
        updated_at: true
      }
    });

    if (!artwork) {
      return res.status(404).json({status: 'error', message: 'Artwork not found'});
    }

    return res.status(200).json(artwork);
  } catch (error: any) {
    console.error(error.message);
    return res.status(500).json({status: 'error', message: 'Internal server error'});
  }
});

// GET artwork image file
router.get('/:id/image', async (req, res) => {
  const {id} = req.params;
  try {
    const artwork = await prisma.artworks.findUnique({
      where: {id},
      select: {filename: true, mimetype: true}
    });

    if (!artwork) {
      return res.status(404).json({status: 'error', message: 'Artwork not found'});
    }

    const filePath = path.join(uploadsDir, artwork.filename);

    // Check if file exists
    if (!fs.existsSync(filePath)) {
      return res.status(404).json({status: 'error', message: 'Image file not found'});
    }

    // Set caching headers for better performance
    res.setHeader('Content-Type', artwork.mimetype);
    res.setHeader('Cache-Control', 'public, max-age=31536000'); // Cache for 1 year
    res.setHeader('ETag', artwork.filename); // Use filename as ETag

    // Send file
    return res.sendFile(filePath);
  } catch (error: any) {
    console.error(error.message);
    return res.status(500).json({status: 'error', message: 'Internal server error'});
  }
});

// POST new artwork
router.post('/', upload.single('image'), async (req, res) => {
  if (!req.file) {
    return res.status(400).json({status: 'error', message: 'No image file uploaded'});
  }

  if (!req.body.title) {
    // Cleanup uploaded file if validation fails
    fs.unlinkSync(req.file.path);
    return res.status(400).json({status: 'error', message: 'Title is required'});
  }

  try {
    const artwork = await prisma.artworks.create({
      data: {
        title: req.body.title,
        filename: req.file.filename,
        mimetype: req.file.mimetype,
        size: req.file.size
      }
    });

    return res.status(201).json({
      id: artwork.id,
      title: artwork.title,
      filename: artwork.filename,
      mimetype: artwork.mimetype,
      size: artwork.size,
      created_at: artwork.created_at,
      updated_at: artwork.updated_at
    });
  } catch (error: any) {
    // Cleanup uploaded file if database operation fails
    fs.unlinkSync(req.file.path);
    console.error(error.message);

    if (error.code === 'P2002') {
      return res.status(409).json({status: 'error', message: 'An artwork with this title already exists'});
    }

    return res.status(500).json({status: 'error', message: 'Internal server error'});
  }
});

// DELETE artwork
router.delete('/:id', async (req, res) => {
  const {id} = req.params;
  try {
    const artwork = await prisma.artworks.findUnique({
      where: {id},
      select: {filename: true}
    });

    if (!artwork) {
      return res.status(404).json({status: 'error', message: 'Artwork not found'});
    }

    // Delete from database
    await prisma.artworks.delete({where: {id}});

    // Delete file from disk
    const filePath = path.join(uploadsDir, artwork.filename);
    if (fs.existsSync(filePath)) {
      fs.unlinkSync(filePath);
    }

    return res.status(200).json({status: 'success', message: 'Artwork deleted'});
  } catch (error: any) {
    console.error(error.message);
    return res.status(500).json({status: 'error', message: 'Internal server error'});
  }
});

export default router;
