const multer = require('multer')
const { S3Client, PutObjectCommand, DeleteObjectCommand } = require('@aws-sdk/client-s3')
const NewsService = require('../../services/news/NewsService')
const { logger } = require('../../middleware/logger')

const PREFIX = 'news/'

function buildImageUrlFromKey(key) {
  if (!key) return ''
  const endpoint = process.env.EXOSCALE_ENDPOINT || ''
  const bucket = process.env.EXOSCALE_BUCKET || ''
  if (endpoint.startsWith('http')) {
    return `${endpoint.replace(/\/$/, '')}/${bucket}/${key}`
  }
  return key
}

exports.list = async (req, res) => {
  try {
    const rows = await NewsService.list()
    const data = (rows || []).map(r => ({
      id: r.id,
      title: r.title,
      summary: r.summary,
      content: r.content,
      slug: r.slug,
      category: r.category,
      is_active: !!r.is_active,
      published_at: r.published_at,
      created_at: r.created_at,
      updated_at: r.updated_at,
      imageUrl: r.object_storage_id ? buildImageUrlFromKey(r.object_storage_id) : ''
    }))
    res.json({ success: true, data })
  } catch (e) {
    logger.error('[NewsController.list] error', { msg: e.message })
    res.status(500).json({ error: 'Failed to load news' })
  }
}

exports.listActive = async (req, res) => {
  try {
    const rows = await NewsService.list()
    const data = (rows || [])
      .filter(r => r.is_active)
      .map(r => ({
        id: r.id,
        title: r.title,
        summary: r.summary,
        content: r.content,
        slug: r.slug,
        category: r.category,
        published_at: r.published_at,
        imageUrl: r.object_storage_id ? buildImageUrlFromKey(r.object_storage_id) : ''
      }))
    res.json({ success: true, data })
  } catch (e) {
    logger.error('[NewsController.listActive] error', { msg: e.message })
    res.status(500).json({ error: 'Failed to load news' })
  }
}

exports.getPublic = async (req, res) => {
  try {
    const { slug } = req.params || {}
    if (!slug) return res.status(400).json({ error: 'slug is required' })
    const r = await NewsService.get(slug)
    if (!r || !r.is_active) return res.status(404).json({ error: 'Not found' })
    const data = {
      id: r.id,
      title: r.title,
      summary: r.summary,
      content: r.content,
      slug: r.slug,
      category: r.category,
      published_at: r.published_at,
      imageUrl: r.object_storage_id ? buildImageUrlFromKey(r.object_storage_id) : ''
    }
    res.json({ success: true, data })
  } catch (e) {
    logger.error('[NewsController.getPublic] error', { msg: e.message })
    res.status(500).json({ error: 'Failed to load news item' })
  }
}

exports.create = async (req, res) => {
  try {
    const { title, summary, content, slug, category, isActive, publishedAt } = req.body
    if (!title || !slug) {
      return res.status(400).json({ success: false, error: 'Title and slug are required' })
    }
    let objectKey = null
    let originalFilename = null

    if (req.file) {
      const allowedMime = ['image/jpeg','image/png','image/webp','image/svg+xml']
      if (!allowedMime.includes(req.file.mimetype)) {
        return res.status(400).json({ success: false, error: 'Invalid image type. Allowed: JPG, PNG, WebP, SVG' })
      }
      if (req.file.size > 5 * 1024 * 1024) {
        return res.status(400).json({ success: false, error: 'Image exceeds 5MB limit' })
      }
      const s3 = new S3Client({
        region: process.env.EXOSCALE_REGION,
        endpoint: process.env.EXOSCALE_ENDPOINT,
        credentials: {
          accessKeyId: process.env.EXOSCALE_ACCESS_KEY,
          secretAccessKey: process.env.EXOSCALE_SECRET_KEY,
        },
      })
      originalFilename = req.file.originalname
      const key = `${PREFIX}${Date.now()}_${originalFilename.replace(/\s+/g, '_')}`
      await s3.send(new PutObjectCommand({ 
        Bucket: process.env.EXOSCALE_BUCKET, 
        Key: key, 
        Body: req.file.buffer, 
        ContentType: req.file.mimetype,
        ACL: 'public-read'
      }))
      objectKey = key
      logger.info('[NewsController.create] uploaded image', { key })
    }

    let id
    try {
      id = await NewsService.create({
      title,
      summary,
      content,
      slug,
      category,
      object_storage_id: objectKey,
      original_filename: originalFilename,
      is_active: isActive ? 1 : 0,
      published_at: publishedAt || null,
      })
    } catch (err) {
      const msg = err && err.message ? err.message : String(err)
      // Handle duplicate slug gracefully
      if (msg.includes('ER_DUP_ENTRY') || msg.toLowerCase().includes('duplicate')) {
        return res.status(409).json({ success: false, error: 'Slug already exists' })
      }
      logger.error('[NewsController.create] db error', { msg })
      return res.status(500).json({ success: false, error: 'Database error while creating news' })
    }

    res.json({ success: true, data: { id } })
  } catch (e) {
    logger.error('[NewsController.create] error', { msg: e.message })
    res.status(500).json({ success: false, error: e.message || 'Failed to create news' })
  }
}

exports.update = async (req, res) => {
  try {
    const { id } = req.params
    const { title, summary, content, slug, category, isActive, publishedAt, removeImage } = req.body
    const existing = await NewsService.get(id)
    if (!existing) return res.status(404).json({ error: 'Not found' })

    let objectKey = existing.object_storage_id
    let originalFilename = existing.original_filename

    if (removeImage && objectKey) {
      try {
        const s3 = new S3Client({
          region: process.env.EXOSCALE_REGION,
          endpoint: process.env.EXOSCALE_ENDPOINT,
          credentials: {
            accessKeyId: process.env.EXOSCALE_ACCESS_KEY,
            secretAccessKey: process.env.EXOSCALE_SECRET_KEY,
          },
        })
        await s3.send(new DeleteObjectCommand({ Bucket: process.env.EXOSCALE_BUCKET, Key: objectKey }))
      } catch (err) {
        logger.error('[NewsController.update] delete image error', { msg: err.message })
      }
      objectKey = null
      originalFilename = null
    }

    if (req.file) {
      const allowedMime = ['image/jpeg','image/png','image/webp','image/svg+xml']
      if (!allowedMime.includes(req.file.mimetype)) {
        return res.status(400).json({ success: false, error: 'Invalid image type. Allowed: JPG, PNG, WebP, SVG' })
      }
      if (req.file.size > 5 * 1024 * 1024) {
        return res.status(400).json({ success: false, error: 'Image exceeds 5MB limit' })
      }
      const s3 = new S3Client({
        region: process.env.EXOSCALE_REGION,
        endpoint: process.env.EXOSCALE_ENDPOINT,
        credentials: {
          accessKeyId: process.env.EXOSCALE_ACCESS_KEY,
          secretAccessKey: process.env.EXOSCALE_SECRET_KEY,
        },
      })
      const newKey = `${PREFIX}${Date.now()}_${req.file.originalname.replace(/\s+/g, '_')}`
      await s3.send(new PutObjectCommand({ 
        Bucket: process.env.EXOSCALE_BUCKET, 
        Key: newKey, 
        Body: req.file.buffer, 
        ContentType: req.file.mimetype,
        ACL: 'public-read'
      }))
      objectKey = newKey
      originalFilename = req.file.originalname
      logger.info('[NewsController.update] uploaded new image', { key: newKey })
    }

    await NewsService.update(id, {
      title,
      summary,
      content,
      slug,
      category,
      object_storage_id: objectKey,
      original_filename: originalFilename,
      is_active: isActive !== undefined ? (isActive ? 1 : 0) : undefined,
      published_at: publishedAt !== undefined ? (publishedAt || null) : undefined,
    })

    res.json({ success: true })
  } catch (e) {
    logger.error('[NewsController.update] error', { msg: e.message })
    res.status(500).json({ error: 'Failed to update news' })
  }
}

exports.updateStatus = async (req, res) => {
  try {
    const { id } = req.params
    const { isActive } = req.body
    await NewsService.update(id, { is_active: isActive ? 1 : 0 })
    res.json({ success: true })
  } catch (e) {
    logger.error('[NewsController.updateStatus] error', { msg: e.message })
    res.status(500).json({ error: 'Failed to update status' })
  }
}

exports.delete = async (req, res) => {
  try {
    const { id } = req.params
    const existing = await NewsService.get(id)
    if (!existing) return res.status(404).json({ error: 'Not found' })
    if (existing.object_storage_id) {
      try {
        const s3 = new S3Client({
          region: process.env.EXOSCALE_REGION,
          endpoint: process.env.EXOSCALE_ENDPOINT,
          credentials: {
            accessKeyId: process.env.EXOSCALE_ACCESS_KEY,
            secretAccessKey: process.env.EXOSCALE_SECRET_KEY,
          },
        })
        await s3.send(new DeleteObjectCommand({ Bucket: process.env.EXOSCALE_BUCKET, Key: existing.object_storage_id }))
      } catch (err) {
        logger.error('[NewsController.delete] delete image error', { msg: err.message })
      }
    }
    await NewsService.delete(id)
    res.json({ success: true })
  } catch (e) {
    logger.error('[NewsController.delete] error', { msg: e.message })
    res.status(500).json({ error: 'Failed to delete news' })
  }
}
