require('dotenv').config();

// Import required modules
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const db = require('./db');
const multer = require('multer');
const axios = require('axios');
const fs = require('fs');
const session = require('express-session');
const nodemailer = require('nodemailer');
const { createOrder } = require('./public/js/payment');

// Create Express app
const app = express();
app.set('view engine', 'ejs');

// Middleware to parse request body
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

app.use(session({
  secret: process.env.SESSION_SECRET,
  resave: false,
  saveUninitialized: true,
  cookie: { secure: false } // Set to true if using HTTPS
}));

// Serve static files from the 'public' directory
app.use(express.static(path.join(__dirname, 'public')));
app.set('views', path.join(__dirname, 'views'));

app.get('/css/payment.css', (req, res) => {
  res.setHeader('Content-Type', 'text/css');
  res.sendFile(path.join(__dirname, 'public', 'css', 'payment.css'));
});

// Serve the 'registration.html' file when root URL is accessed
app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, 'views', 'registration.html'));
});

// Serve the 'registration.html' file when '/register' is accessed
app.get('/register', (req, res) => {
  res.sendFile(path.join(__dirname, 'views', 'registration.html'));
});

app.get('/payment', (req, res) => {
  const { orderId, sponsorshipLevel, company_id } = req.session;
  res.render('payment', { orderId, sponsorshipLevel, company_id });
});

app.get('/documentUpload', (req, res) => {
  const companyId = req.session.companyId;
  res.render('documentUpload', { company_id: companyId });
});

app.get('/payment-successful', (req, res) => {
  const companyId = req.session.companyId;
  res.render('payment-successful', { company_id: companyId });
});

app.get('/upload-success', (req, res) => {
  res.render('upload-success'); // Render the success page view
});

// Handle payment success callback from Razorpay
app.post('/payment-successful', async (req, res) => {
  try {
    const SECRET = "12345678951";
    const paymentDetails = req.body;
    console.log("ok done");
    res.json({ status: 'ok' });

    const success = await handlePaymentSuccess(paymentDetails);

    if (success) {
      const orderId = paymentDetails.payload.payment.entity.order_id;
      console.log("order id after payment successful::" + orderId);
      const updateSql = 'UPDATE companies SET status = ? WHERE razorpay_order_id = ?';
      db.query(updateSql, ['paid', orderId], (err) => {
        if (err) {
          console.error('Error updating registration status:', err);
          return res.status(500).send('Error updating registration status');
        }

        const { order_id, id, status } = paymentDetails.payload.payment.entity;
        const amount = paymentDetails.payload.payment.entity.amount / 100;
        const timestamp = paymentDetails.payload.payment.entity.created_at;
        const created_at = new Date(timestamp * 1000).toISOString().slice(0, 19).replace('T', ' ');

        const insertPaymentSql = 'INSERT INTO orders (razorpay_order_id, amount, payment_id, status, created_at) VALUES (?, ?, ?, ?, ?)';
        db.query(insertPaymentSql, [order_id, amount, id, status, created_at], (err) => {
          if (err) {
            console.error('Error updating payment details:', err);
            return res.status(500).send('Error updating payment details');
          }
          // Redirect to document upload page
          res.redirect('/documentUpload');
        });
      });
    } else {
      res.status(400).send('Payment failed');
    }
  } catch (error) {
    console.error('Error handling payment success:', error);
    res.status(500).send('Internal server error');
  }
});

// Implement endpoint for creating payment
app.post('/createPayment', async (req, res) => {
  const { orderId, sponsorshipLevel } = req.session; // Get data from session
  try {
    let paymentAmount;
    if (sponsorshipLevel === '1') {
      paymentAmount = 200000;
    } else if (sponsorshipLevel === '2') {
      paymentAmount = 300000;
    } else {
      paymentAmount = 80000;
    }
    const paymentDetails = await createPayment(orderId, paymentAmount);
    res.json(paymentDetails);
  } catch (error) {
    console.error('Error creating payment:', error);
    res.status(500).send('Error creating payment');
  }
});

// Handle registration form submission
app.post('/register', async (req, res) => {
  const {
    company_name, primary_contact_name, email, primary_country_code, primary_contact_number,
    address, website_url, secondary_contact_name, secondary_country_code, secondary_contact_number,
    ceo_name, want_to_sponsor, accepted_terms, password
  } = req.body;
  const selectedSponsorshipLevel = req.body.selected_sponsorship_level;

  const full_primary_contact_number = `+${primary_country_code}${primary_contact_number}`;
  const full_secondary_contact_number = secondary_contact_number ? `+${secondary_country_code}${secondary_contact_number}` : null;

  let sponsorshipLevelValue;
  let paymentAmount;
  if (selectedSponsorshipLevel === 'silver') {
    sponsorshipLevelValue = 1;
    paymentAmount = 200000;
  } else if (selectedSponsorshipLevel === 'golden') {
    sponsorshipLevelValue = 2;
    paymentAmount = 300000;
  } else {
    sponsorshipLevelValue = 0;
    paymentAmount = 80000;
  }

  try {
    const orderId = await createOrder(paymentAmount);
    console.log("Order ID:", orderId);

    const insertCompanySql = `INSERT INTO companies (company_name, primary_contact_name, email, primary_contact_number, address, website_url, 
      secondary_contact_name, secondary_contact_number, ceo_name, want_to_sponsor, accepted_terms, password, status, sponsorshipLevel, razorpay_order_id) 
      VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`;

    db.query(insertCompanySql, [
      company_name, primary_contact_name, email, full_primary_contact_number, address, website_url,
      secondary_contact_name, full_secondary_contact_number, ceo_name, want_to_sponsor, accepted_terms, password, 'unpaid',
      sponsorshipLevelValue, orderId
    ], async (err, result) => {
      if (err) {
        console.error('Error registering company:', err);
        return res.status(500).send('Error registering company');
      }

      const companyId = result.insertId;
      req.session.companyId = companyId;
      req.session.orderId = orderId;
      req.session.sponsorshipLevel = sponsorshipLevelValue;

      // Redirect to payment page
      res.redirect('/payment');
    });
  } catch (error) {
    console.error('Error creating Razorpay order:', error);
    res.status(500).send('Error processing payment');
  }
});

// Multer setup for file upload
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'uploads/');
  },
  filename: function (req, file, cb) {
    cb(null, Date.now() + path.extname(file.originalname));
  }
});

const upload = multer({
  storage: storage,
  limits: { fileSize: 10 * 1024 * 1024 } // 10 MB file size limit
}).fields([
  { name: 'document[]', maxCount: 10 },
  { name: 'image[]', maxCount: 10 },
  { name: 'video[]', maxCount: 10 }
]);

const bunnyNetStorageZone = 'arenaa-s1';
const bunnyNetApiKey = '8eb18cc0-4429-4205-a9c3892c637e-dc71-4de2';
const bunnyNetBaseUrl = `https://storage.bunnycdn.com/${bunnyNetStorageZone}/`;

app.post('/documentUpload', upload, async (req, res) => {
  const { booth_id } = req.body;
  const companyId = req.session.companyId;
  const files = req.files;

  if (!companyId) {
    return res.status(400).send('Company ID is missing');
  }

  try {
    const updateCompaniesSql = 'UPDATE companies SET selected_booth = ? WHERE company_id = ?';
    await new Promise((resolve, reject) => {
      db.query(updateCompaniesSql, [booth_id, companyId], (err, result) => {
        if (err) {
          reject(err);
        } else {
          resolve(result);
        }
      });
    });

    const mediaUploads = [];
    for (const [fieldName, fileArray] of Object.entries(files)) {
      let folderPath = '';
      if (fieldName === 'document[]') {
        folderPath = `${companyId}/documents/`;
      } else if (fieldName === 'image[]') {
        folderPath = `${companyId}/images/`;
      } else if (fieldName === 'video[]') {
        folderPath = `${companyId}/videos/`;
      }

      for (const file of fileArray) {
        const filePath = file.path;
        const bunnyFilePath = `${folderPath}${file.filename}`;

        const fileContent = fs.readFileSync(filePath);

        const bunnyNetResponse = await axios.put(`${bunnyNetBaseUrl}${bunnyFilePath}`, fileContent, {
          headers: {
            AccessKey: bunnyNetApiKey,
            'Content-Type': 'application/octet-stream'
          }
        });

        const fileType = fieldName === 'document[]' ? 'pdf' : file.mimetype.split('/')[0];

        const insertMediaSql = 'INSERT INTO media (company_id, media_type, url) VALUES (?, ?, ?)';
        await new Promise((resolve, reject) => {
          db.query(insertMediaSql, [companyId, fileType, bunnyNetResponse.data.Url], (err, result) => {
            if (err) {
              reject(err);
            } else {
              resolve(result);
            }
          });
        });

        mediaUploads.push({ path: filePath });
      }
    }

    res.redirect('/upload-success');
  } catch (error) {
    console.error('Error uploading files:', error);
    res.status(500).send('File upload failed');
  }
});

// Start the server on port 3000
const port = 3000;
app.listen(port, () => {
  console.log(`Server started on http://localhost:${port}`);
});
