const { addBaseUrlToImages } = require('../utils/imageHelper');
const CampLocation = require('../models/campLocation');

// -------------------- Public (read-only) helpers --------------------
// Get camp location data from MongoDB
const getCampLocationData = async () => {
  const campLocation = await CampLocation.findOne().sort({ updatedAt: -1 });
  if (!campLocation) return null;
  return campLocation.toObject ? campLocation.toObject() : campLocation;
};

// -------------------- Admin (CRUD on CampLocation model) helpers --------------------
// Default shape for CampLocation documents
const getDefaultCampLocationData = () => ({
  metadata: { title: '', description: '', keywords: '' },
  hero: { title: '', subtitle: '', backgroundImage: '' },
  camps: [],
  locations: [],
  locationsSection: { title: '', description: '' },
  intro: { title: '', description: '' },
  map: {
    coordinates: { lat: 0, lng: 0 },
    zoom: 15,
    location: '',
    markerTitle: '',
    tileLayer: {
      url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
      attribution: '',
      maxZoom: 18,
      minZoom: 0
    }
  },
  faq: [],
  faqSection: { title: '', description: '' },
  welcomeQuote: { text: '', author: '' },
  securityConcept: { title: '', description: '', items: [] }
});

// Get latest stored CampLocation document or default
const getStoredCampLocation = async () => {
  const campLocation = await CampLocation.findOne().sort({ updatedAt: -1 });
  if (!campLocation) return getDefaultCampLocationData();
  return campLocation.toObject ? campLocation.toObject() : campLocation;
};

// -------------------- Public exports --------------------
// API endpoint to return camp location JSON
exports.api = async (req, res) => {
  try {
    const campLocationData = await getCampLocationData();
    const baseUrl = process.env.BACKEND_URL || `${req.protocol}://${req.get('host')}`;
    const processed = addBaseUrlToImages(campLocationData || {}, baseUrl);
    return res.json(processed);
  } catch (err) {
    console.error('campLocation.api error:', err);
    return res.status(500).json({ error: 'Error loading camp location data' });
  }
};

// API endpoint to return an array of CampLocation records (for frontend listing)
exports.apiList = async (req, res) => {
  try {
    const docs = await CampLocation.find().sort({ updatedAt: -1 }).lean();
    const baseUrl = process.env.BACKEND_URL || `${req.protocol}://${req.get('host')}`;
    const processed = (docs || []).map((d) => addBaseUrlToImages(d || {}, baseUrl));
    return res.json(processed);
  } catch (err) {
    console.error('campLocation.apiList error:', err);
    return res.status(500).json({ error: 'Error loading camp location list' });
  }
};

// -------------------- Admin exports --------------------
// Display camp location management page
exports.index = async (req, res) => {
  try {
    // Set cache control headers to prevent caching
    res.set({
      'Cache-Control': 'no-store, no-cache, must-revalidate, private',
      'Pragma': 'no-cache',
      'Expires': '0'
    });

    const data = await getStoredCampLocation();
    const items = await CampLocation.find().sort({ updatedAt: -1 }).limit(10);

    res.render('admin/campLocation/index', {
      layout: 'layouts/main',
      title: 'Camp Location Management',
      data,
      items,
      frontendUrl: process.env.FRONTEND_URL || `${req.protocol}://${req.get('host')}`,
      currentPath: req.path,
      user: req.session.user
    });
  } catch (err) {
    console.error(err);
    req.flash('error_msg', 'Error loading camp location data');
    res.redirect('/admin/dashboard');
  }
};

// Display create form
exports.createForm = async (req, res) => {
  try {
    const data = getDefaultCampLocationData();

    res.render('admin/campLocation/create', {
      layout: 'layouts/main',
      title: 'Create Camp Location',
      data,
      currentPath: req.path,
      user: req.session.user
    });
  } catch (err) {
    console.error(err);
    req.flash('error_msg', 'Error loading create form');
    res.redirect('/admin/camp-location');
  }
};

// Create new CampLocation record
exports.create = async (req, res) => {
  try {
    const campLocationData = {
      metadata: JSON.parse(req.body.metadata || '{}'),
      hero: JSON.parse(req.body.hero || '{}'),
      camps: JSON.parse(req.body.camps || '[]'),
      locations: JSON.parse(req.body.locations || '[]'),
      locationsSection: JSON.parse(req.body.locationsSection || '{}'),
      intro: JSON.parse(req.body.intro || '{}'),
      map: JSON.parse(req.body.map || '{}'),
      faq: JSON.parse(req.body.faq || '[]'),
      faqSection: JSON.parse(req.body.faqSection || '{}'),
      welcomeQuote: JSON.parse(req.body.welcomeQuote || '{}'),
      securityConcept: JSON.parse(req.body.securityConcept || '{}')
    };

    const newCampLocation = new CampLocation(campLocationData);
    await newCampLocation.save();

    req.flash('success_msg', 'Camp Location created successfully');
    res.redirect('/admin/camp-location');
  } catch (err) {
    console.error('Create error:', err);
    req.flash('error_msg', `Create error: ${err.message || 'Unknown'}`);
    res.redirect('/admin/camp-location/create');
  }
};

// Display edit form
exports.editForm = async (req, res) => {
  try {
    const campLocation = await CampLocation.findById(req.params.id);

    if (!campLocation) {
      req.flash('error_msg', 'Camp Location record not found');
      return res.redirect('/admin/camp-location');
    }

    res.render('admin/campLocation/edit', {
      layout: 'layouts/main',
      title: 'Edit Camp Location',
      data: campLocation.toObject ? campLocation.toObject() : campLocation,
      currentPath: req.path,
      user: req.session.user
    });
  } catch (err) {
    console.error(err);
    req.flash('error_msg', 'Error loading edit form');
    res.redirect('/admin/camp-location');
  }
};

// Update CampLocation record
exports.update = async (req, res) => {
  try {
    // Get current data
    const currentData = await getStoredCampLocation();

    // List of sections to update
    const sections = [
      'metadata',
      'hero',
      'camps',
      'locations',
      'locationsSection',
      'intro',
      'map',
      'faq',
      'faqSection',
      'welcomeQuote',
      'securityConcept'
    ];
    const errors = [];
    let hasChanges = false;

    // Create updated data object
    const updatedData = {
      ...(currentData.toObject ? currentData.toObject() : currentData)
    };

    // Process each section
    sections.forEach((section) => {
      try {
        if (!req.body[section]) {
          console.warn(`No data for section: ${section}`);
          return;
        }

        const newSectionData = JSON.parse(req.body[section]);
        const currentSectionData = currentData[section];
        const sectionHasChanges =
          JSON.stringify(newSectionData) !== JSON.stringify(currentSectionData);

        if (sectionHasChanges) {
          updatedData[section] = newSectionData;
          hasChanges = true;
        }
      } catch (error) {
        console.error(`Error processing section ${section}:`, error);
        errors.push(`Error processing ${section} data: ${error.message}`);
      }
    });

    if (errors.length > 0) {
      req.flash('error_msg', `Data processing error: ${errors[0]}`);
      return req.session.save(() => res.redirect('/admin/camp-location'));
    }

    if (!hasChanges) {
      req.flash('info_msg', 'No changes were made');
      return req.session.save(() => res.redirect('/admin/camp-location'));
    }

    try {
      // Only update existing document; do not create a new one here
      if (!currentData || !currentData._id) {
        req.flash('error_msg', 'No existing Camp Location record to update. Create one first.');
        return req.session.save(() => res.redirect('/admin/camp-location'));
      }

      // Update document and ensure it's saved to MongoDB
      const updatedDoc = await CampLocation.findByIdAndUpdate(
        currentData._id, 
        updatedData, 
        {
          new: true,
          runValidators: true,
          useFindAndModify: false
        }
      );

      // Verify the update was successful
      if (!updatedDoc) {
        throw new Error('Failed to update document');
      }

      // Force a save to ensure MongoDB commits the changes
      await updatedDoc.save();

      console.log('✓ Camp location updated successfully in MongoDB');
      console.log('✓ Document ID:', updatedDoc._id);
      console.log('✓ Updated at:', updatedDoc.updatedAt);

      req.flash('success_msg', 'Camp location data updated successfully');
      // Redirect back to the same page with cache-busting parameter to force refresh
      const timestamp = Date.now();
      return req.session.save(() => res.redirect(`/admin/camp-location?updated=${timestamp}`));
    } catch (dbError) {
      console.error('Database error:', dbError);
      req.flash('error_msg', `Database error: ${dbError.message || 'Unknown'}`);
      return req.session.save(() => res.redirect('/admin/camp-location'));
    }
  } catch (err) {
    console.error('Update error:', err);
    req.flash('error_msg', `Update error: ${err.message || 'Unknown'}`);
    return req.session.save(() => res.redirect('/admin/camp-location'));
  }
};

// Delete CampLocation record
exports.delete = async (req, res) => {
  try {
    const campLocation = await CampLocation.findById(req.params.id);

    if (!campLocation) {
      req.flash('error_msg', 'Camp Location record not found');
      return res.redirect('/admin/camp-location');
    }

    await CampLocation.findByIdAndDelete(req.params.id);

    req.flash('success_msg', 'Camp Location record deleted successfully');
    res.redirect('/admin/camp-location');
  } catch (err) {
    console.error('Delete error:', err);
    req.flash('error_msg', `Delete error: ${err.message || 'Unknown'}`);
    res.redirect('/admin/camp-location');
  }
};

// Preview CampLocation record
exports.preview = async (req, res) => {
  try {
    const campLocation = await CampLocation.findById(req.params.id);

    if (!campLocation) {
      return res.status(404).json({ error: 'Camp Location record not found' });
    }

    const baseUrl = process.env.BACKEND_URL || `${req.protocol}://${req.get('host')}`;
    const processedData = addBaseUrlToImages(
      campLocation.toObject ? campLocation.toObject() : campLocation,
      baseUrl
    );
    res.json(processedData);
  } catch (err) {
    console.error('Preview error:', err);
    res.status(500).json({ error: 'Error loading preview data' });
  }
};
