import express from 'express';
import SubmitDirectory from '../models/submitDirectory.js';
import { authenticate } from '../middleware/authMiddleware.js';
import { verifyPayPalOrder } from '../middleware/paypalVerification.js';
import { sendDirectorySubmissionEmail } from '../utils/emailService.js';
import { User } from '../models/user.js';
import { uploadToDropbox, generateUniqueFilename, getFileExtensionFromBase64 } from '../utils/dropboxService.js';
import { getPrice } from '../config/pricing.js';

const router = express.Router();

// ✅ PHASE 1: Create pending directory submission (no payment required yet)
router.post('/create', authenticate, async (req, res) => {
  try {
    const userId = req.user.id;

    console.log('📝 Directory submission (PENDING) request received');

    const {
      websiteUrl,
      screenshot,
      title,
      description,
      companyLogo,
      country,
      contactEmail,
      contactNumber,
      profile,
      openTo,
      foundingYear,
      totalEmployees,
      budget,
      languages,
      facebook,
      instagram,
      twitter,
      linkedin,
      tiktok,
      youtube,
    } = req.body;


    // Check if the website URL already exists
    const existingURL = await SubmitDirectory.findOne({ websiteUrl });
    if (existingURL) {
      console.log(`❌ Website URL already exists: ${websiteUrl}`);
      return res.status(409).json({
        ok: false,
        error: "URL_ALREADY_EXISTS",
        message: "A directory with this URL has already been submitted"
      });
    }

    // Parse languages if it's a string
    let parsedLanguages = languages;
    if (typeof languages === 'string') {
      try {
        parsedLanguages = JSON.parse(languages);
      } catch (e) {
        parsedLanguages = [languages];
      }
    }

    // ✅ Upload screenshot and company logo to Dropbox
    let screenshotUrl, companyLogoUrl;

    if (screenshot) {
      const screenshotExt = getFileExtensionFromBase64(screenshot);
      const screenshotFilename = generateUniqueFilename(`${title}-screenshot.${screenshotExt}`, 'directory');
      screenshotUrl = await uploadToDropbox(screenshot, screenshotFilename, '/directory-submissions');
      console.log('✅ Screenshot uploaded to Dropbox:', screenshotUrl);
    } else {
      return res.status(400).json({
        ok: false,
        error: "VALIDATION_ERROR",
        message: "Screenshot is required."
      });
    }

    if (companyLogo) {
      const logoExt = getFileExtensionFromBase64(companyLogo);
      const logoFilename = generateUniqueFilename(`${title}-logo.${logoExt}`, 'directory');
      companyLogoUrl = await uploadToDropbox(companyLogo, logoFilename, '/directory-submissions');
      console.log('✅ Company logo uploaded to Dropbox:', companyLogoUrl);
    } else {
      return res.status(400).json({
        ok: false,
        error: "VALIDATION_ERROR",
        message: "Company logo is required."
      });
    }

    // Create the payload with PENDING status - no payment info yet
    const payload = {
      submittedBy: userId,
      websiteUrl,
      screenshot: screenshotUrl,
      title,
      description,
      companyLogo: companyLogoUrl,
      country,
      contactEmail,
      contactNumber,
      profile,
      openTo,
      foundingYear,
      totalEmployees,
      budget,
      languages: parsedLanguages,
      facebook: facebook || "",
      instagram: instagram || "",
      twitter: twitter || "",
      linkedin: linkedin || "",
      tiktok: tiktok || "",
      youtube: youtube || "",
      status: 'pending_payment',
      // ✅ Generate temporary unique paymentOrderID to avoid null duplicate key errors
      paymentOrderID: `PENDING_DIR_${Date.now()}_${userId}_${Math.random().toString(36).substr(2, 9)}`,
    };

    // Save the pending directory submission to the database
    const doc = await SubmitDirectory.create(payload);

    console.log("✅ Pending directory submission created: " + doc._id);

    // Get the price for this service
    const servicePrice = getPrice('directory');

    return res.status(201).json({
      ok: true,
      data: doc,
      price: servicePrice,
      message: "Submission created successfully. Please complete payment to publish."
    });
  } catch (err) {
    console.error("❌ Pending directory submission error:", err);

    if (err?.code === 11000) {
      const duplicateField = Object.keys(err.keyValue)[0];
      let message = "A submission with this data already exists.";

      if (duplicateField === 'companyUrl') {
        message = "This website URL has already been submitted.";
      }

      return res.status(409).json({
        ok: false,
        error: "DUPLICATE_KEY",
        message: message,
        field: duplicateField,
        value: err.keyValue[duplicateField],
      });
    }
    return res.status(500).json({ ok: false, error: "SERVER_ERROR", message: err.message });
  }
});

// ✅ PHASE 2: Confirm payment and publish directory submission
router.post('/confirm-payment', authenticate, async (req, res) => {
  try {
    const userId = req.user.id;

    console.log('💳 Directory payment confirmation request received');

    const {
      submissionId,
      paymentOrderID,
      paymentAmount,
      couponCode,
      isFreeSubmission,
    } = req.body;

    if (!submissionId) {
      return res.status(400).json({
        ok: false,
        error: "SUBMISSION_ID_REQUIRED",
        message: "Submission ID is required"
      });
    }

    // Find the pending submission
    const submission = await SubmitDirectory.findById(submissionId);

    if (!submission) {
      return res.status(404).json({
        ok: false,
        error: "SUBMISSION_NOT_FOUND",
        message: "Submission not found"
      });
    }

    // Verify the submission belongs to the current user
    if (submission.submittedBy.toString() !== userId.toString()) {
      return res.status(403).json({
        ok: false,
        error: "UNAUTHORIZED",
        message: "You are not authorized to confirm payment for this submission"
      });
    }

    // Check if submission is already published
    if (submission.status === 'published') {
      return res.status(400).json({
        ok: false,
        error: "ALREADY_PUBLISHED",
        message: "This submission has already been published"
      });
    }

    // ✅ CRITICAL: Check if this is a free submission (price = 0 due to coupon)
    const isFree = isFreeSubmission === true && paymentAmount === 0;

    let order = null;

    if (isFree) {
      // For free submissions, verify coupon instead of payment
      if (!couponCode) {
        return res.status(400).json({
          ok: false,
          error: "COUPON_REQUIRED",
          message: "Coupon code is required for free submission"
        });
      }

      console.log('🎟️ Processing free directory submission with coupon:', couponCode);

      // Update submission with coupon info
      submission.paymentOrderID = `FREE_DIR_${Date.now()}_${userId}`;
      submission.paymentStatus = 'FREE_COUPON';
      submission.paymentAmount = 0;
      submission.paymentCurrency = 'USD';
      submission.paymentDate = new Date();
      submission.paymentVerified = true;
      submission.couponCode = couponCode;
      submission.isFreeSubmission = true;
      submission.status = 'published';

    } else {
      // Regular paid submission - verify PayPal payment
      if (!paymentOrderID) {
        submission.status = 'payment_failed';
        await submission.save();

        return res.status(400).json({
          ok: false,
          error: "PAYMENT_REQUIRED",
          message: "Payment order ID is required for submission",
          canRetry: true,
          submissionId: submission._id
        });
      }

      // Check if this payment has already been used
      const existingPayment = await SubmitDirectory.findOne({
        paymentOrderID,
        _id: { $ne: submissionId }
      });
      if (existingPayment) {
        console.log(`Payment ID already exists: ${paymentOrderID}`);
        return res.status(409).json({
          ok: false,
          error: "PAYMENT_ALREADY_USED",
          message: "This payment has already been used for another submission"
        });
      }

      // Verify payment with PayPal
      console.log('🔍 Verifying PayPal payment:', paymentOrderID);
      const verificationResult = await verifyPayPalOrder(paymentOrderID);

      if (!verificationResult.success) {
        submission.status = 'payment_failed';
        await submission.save();

        return res.status(400).json({
          ok: false,
          error: "PAYMENT_VERIFICATION_FAILED",
          message: "Payment verification failed. Please try again.",
          canRetry: true,
          submissionId: submission._id
        });
      }

      order = verificationResult.order;

      // Check if payment is completed or approved
      if (order.status !== 'COMPLETED' && order.status !== 'APPROVED') {
        submission.status = 'payment_failed';
        await submission.save();

        return res.status(400).json({
          ok: false,
          error: "PAYMENT_NOT_COMPLETED",
          message: `Payment status is ${order.status}. Expected COMPLETED or APPROVED.`,
          canRetry: true,
          submissionId: submission._id
        });
      }

      // Update submission with payment info
      submission.paymentOrderID = order.id;
      submission.paymentStatus = order.status;
      submission.paymentAmount = parseFloat(order.amount);
      submission.paymentCurrency = order.currency;
      submission.payerEmail = order.payerEmail;
      submission.payerName = order.payerName;
      submission.paymentDate = new Date();
      submission.paymentVerified = true;
      submission.isFreeSubmission = false;
      submission.status = 'published';
    }

    // Save the updated submission
    await submission.save();

    console.log(isFree
      ? "✅ Free directory submission published with coupon: " + couponCode
      : "✅ Directory submission published with verified payment: " + submission._id
    );

    // Apply coupon if this is a free submission
    if (isFree && couponCode) {
      try {
        const response = await fetch(`${process.env.API_Dep_URL || 'http://localhost:5000'}/api/coupons/apply`, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': req.headers.authorization,
          },
          body: JSON.stringify({
            couponCode: couponCode,
            serviceType: 'directory',
          }),
        });

        if (response.ok) {
          console.log('✅ Coupon applied successfully:', couponCode);
        } else {
          console.warn('⚠️ Failed to apply coupon, but submission completed:', couponCode);
        }
      } catch (couponError) {
        console.error('❌ Error applying coupon:', couponError.message);
      }
    }

    // Get user information for email
    const user = await User.findById(userId);

    // Send confirmation email
    if (user && user.email) {
      console.log("📧 Attempting to send confirmation email to:", user.email);
      try {
        await sendDirectorySubmissionEmail(user.email, {
          userName: user.userName || user.name || "User",
          companyTitle: submission.companyName,
          websiteUrl: submission.companyUrl,
          profile: submission.profile,
          country: submission.country,
          submissionDate: new Date(),
          paymentOrderID: isFree ? 'FREE (Coupon Applied)' : order?.id,
          paymentAmount: isFree ? '0.00' : order?.amount,
          paymentCurrency: 'USD',
        });
        console.log("✅ Confirmation email sent successfully");
      } catch (emailError) {
        console.error("❌ Failed to send confirmation email:", emailError.message);
      }
    }

    return res.status(200).json({
      ok: true,
      data: submission,
      message: "Payment confirmed and directory submission published successfully!"
    });
  } catch (err) {
    console.error("❌ Directory payment confirmation error:", err);
    return res.status(500).json({ ok: false, error: "SERVER_ERROR", message: err.message });
  }
});

// Route to get all submitted directories (GET) - only published
router.get('/directories', async (req, res) => {
  try {
    const { profile, category, budget, country, limit, page } = req.query;

    const filter = {
      // ✅ Show published submissions OR old submissions without status field
      $or: [
        { status: 'published' },
        { status: { $exists: false } } // Old submissions before status field was added
      ]
    };

    if (profile) filter.profile = profile;
    if (category) filter.category = category;
    if (budget) filter.budget = budget;
    if (country) filter.country = country;

    const limitNum = parseInt(limit) || 0;
    const pageNum = parseInt(page) || 1;
    const skip = limitNum > 0 ? (pageNum - 1) * limitNum : 0;

    let query = SubmitDirectory.find(filter)
      .populate("submittedBy", "userName profilePhoto")
      .sort({ createdAt: -1 })
      .lean();

    if (limitNum > 0) {
      query = query.limit(limitNum).skip(skip);
    }

    const directories = await query;
    const total = limitNum > 0 ? await SubmitDirectory.countDocuments(filter) : directories.length;

    res.status(200).json({
      data: directories,
      pagination: limitNum > 0 ? {
        total,
        page: pageNum,
        limit: limitNum,
        pages: Math.ceil(total / limitNum)
      } : null
    });
  } catch (err) {
    res.status(500).json({ message: 'Error fetching directories', error: err.message });
  }
});

// Route to get a single directory by ID
router.get('/directories/:id', async (req, res) => {
  try {
    const { id } = req.params;

    const directory = await SubmitDirectory.findById(id)
      .populate("submittedBy", "userName email profilePhoto")
      .lean();

    if (!directory) {
      return res.status(404).json({
        ok: false,
        message: "Directory not found"
      });
    }

    res.status(200).json({
      ok: true,
      data: directory
    });
  } catch (err) {
    console.error("Error fetching directory:", err);
    res.status(500).json({
      ok: false,
      message: "Error fetching directory",
      error: err.message
    });
  }
});

export default router;
