// routes/website.routes.js
import { Router } from "express";
import WebsiteSubmission from "../models/websiteSubmission.js";
import firebaseAuth from "../middleware/firebaseAuth.js"; // New middleware
import { authenticate } from "../middleware/authMiddleware.js"
import Vote from "../models/vote.js";
import Award from "../models/award.js"
import { verifyPayPalOrder } from "../middleware/paypalVerification.js";
import { sendWebsiteSubmissionEmail } from "../utils/emailService.js";
import { User } from "../models/user.js";
import { uploadToDropbox, generateUniqueFilename, getFileExtensionFromBase64 } from "../utils/dropboxService.js";
const router = Router();

const toStringArray = (v) => {
  if (Array.isArray(v)) return v.map(String).filter(Boolean);
  if (typeof v === "string") {
    return v.split(",").map((s) => s.trim()).filter(Boolean);
  }
  return [];
};



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

    console.log('📝 Website submission (PENDING) request received');
    console.log('📝 Request body keys:', Object.keys(req.body));

    // Destructure all values from req.body directly
    const {
      Submitted_URL,
      Img,
      Title,
      Description,
      Category,
      Technology,
      Tags,
      Colors,
      ProfileType,
      Freelancer_Name,
      URL,
      Country,
    } = req.body;

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

    // ✅ Upload image to Dropbox
    let imageUrl;
    if (Img) {
      const extension = getFileExtensionFromBase64(Img);
      const filename = generateUniqueFilename(`${Title}.${extension}`, 'website');
      imageUrl = await uploadToDropbox(Img, filename, '/website-submissions');
      console.log('✅ Image uploaded to Dropbox:', imageUrl);
    } else {
      return res.status(400).json({
        ok: false,
        error: "VALIDATION_ERROR",
        message: "Website image is required."
      });
    }

    // Normalize multi-select fields (Tags and Colors)
    const normalizedTags = toStringArray(Tags);
    const normalizedColors = toStringArray(Colors);

    // Normalize Category - handle empty array or ensure it's a string
    const normalizedCategory = Array.isArray(Category)
      ? (Category.length > 0 ? Category[0] : '')
      : Category || '';

    // Validate required fields
    if (!normalizedCategory || normalizedCategory.trim() === '') {
      return res.status(400).json({
        ok: false,
        error: "VALIDATION_ERROR",
        message: "Category is required. Please select a category for your submission."
      });
    }

    if (!Title || Title.trim() === '') {
      return res.status(400).json({
        ok: false,
        error: "VALIDATION_ERROR",
        message: "Title is required."
      });
    }

    if (!Submitted_URL || Submitted_URL.trim() === '') {
      return res.status(400).json({
        ok: false,
        error: "VALIDATION_ERROR",
        message: "Website URL is required."
      });
    }

    // Create the payload with PENDING status - no payment info yet
    const payload = {
      Submitted_URL,
      Img: imageUrl,
      Title,
      Description,
      Category: normalizedCategory,
      Technology: Technology || null,
      Tags: normalizedTags,
      Colors: normalizedColors,
      ProfileType,
      Freelancer_Name,
      URL,
      Country,
      submittedBy: userId,
      status: 'pending_payment', // Mark as pending payment
      // ✅ Generate temporary unique paymentOrderID to avoid null duplicate key errors
      paymentOrderID: `PENDING_${Date.now()}_${userId}_${Math.random().toString(36).substr(2, 9)}`,
    };

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

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

    return res.status(201).json({
      ok: true,
      data: doc,
      message: "Submission created successfully. Please complete payment to publish."
    });
  } catch (err) {
    console.error("❌ Pending 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 === 'Submitted_URL') {
        message = "This website URL has already been submitted.";
      } else if (duplicateField === 'URL') {
        message = "This profile URL has already been used.";
      }

      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 submission
router.post("/confirm-payment", authenticate, async (req, res) => {
  try {
    const userId = req.user.id;

    console.log('💳 Payment confirmation request received');

    const {
      submissionId, // ID of the pending submission
      paymentOrderID, // Payment order ID from PayPal
      paymentAmount, // Payment amount (can be 0 for coupon-based free submissions)
      couponCode, // Coupon code for free submissions
      isFreeSubmission, // Flag indicating free submission via coupon
    } = 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 WebsiteSubmission.findById(submissionId);

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

    console.log('🔍 User ID check:', { submittedBy: submission.submittedBy.toString(), userId: userId.toString(), match: submission.submittedBy.toString() === userId.toString() });

    // Verify the submission belongs to the current user
    if (submission.submittedBy.toString() !== userId.toString()) {
      console.log('Authorization check failed:', {
        submissionUserId: submission.submittedBy.toString(),
        currentUserId: 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 or payment already confirmed
    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 submission with coupon:', couponCode);

      // Update submission with coupon info
      submission.paymentOrderID = `FREE_${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) {
        // Mark as payment failed and keep submission for retry
        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, // Allow user to retry payment
          submissionId: submission._id
        });
      }

      // Check if this payment has already been used
      const existingPayment = await WebsiteSubmission.findOne({
        paymentOrderID,
        _id: { $ne: submissionId } // Exclude current submission
      });
      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) {
        // Mark as payment failed but keep submission for retry
        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, // Allow user to retry payment
          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 website submission published with coupon: " + couponCode
      : "✅ Website 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: 'websiteSubmission',
          }),
        });

        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 sendWebsiteSubmissionEmail(user.email, {
          userName: user.userName || user.name || "User",
          websiteTitle: submission.Title,
          websiteUrl: submission.Submitted_URL,
          category: submission.Category,
          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 submission published successfully!"
    });
  } catch (err) {
    console.error("❌ Payment confirmation error:", err);
    return res.status(500).json({ ok: false, error: "SERVER_ERROR", message: err.message });
  }
});



router.get("/", async (req, res) => {
  try {
    const { Awards, ProfileType, Tags, Colors, Category, Technology, Country, limit, page } = req.query;

    let filter = {
      status: 'published' // ✅ Only return published submissions
    };

    // Handle award filtering
    if (Awards) {
      // Find all website IDs that have this award type
      const awardedWebsiteIds = await Award.find({
        awardType: Awards
      }).distinct('websiteId');

      filter._id = { $in: awardedWebsiteIds };
    }

    // Existing filters
    if (ProfileType) filter.ProfileType = ProfileType;
    if (Category) filter.Category = Category;
    if (Technology) filter.Technology = Technology;
    if (Country) filter.Country = Country;

    if (Tags) {
      const tagsArray = Tags.split(",");
      filter.Tags = { $in: tagsArray };
    }

    if (Colors) {
      const colorsArray = Colors.split(",");
      filter.Colors = { $in: colorsArray };
    }

    // Pagination logic
    const limitNum = parseInt(limit) || 0; // 0 means no limit (fetch all)
    const pageNum = parseInt(page) || 1;
    const skip = limitNum > 0 ? (pageNum - 1) * limitNum : 0;

    // Return all fields - don't limit the data returned
    let query = WebsiteSubmission.find(filter)
      .populate("submittedBy", "userName profilePhoto")
      .populate({
        path: "Votes",
        populate: {
          path: "submittedBy",  // This populates the user inside each vote
          select: "_id userName profilePhoto"  // Include the fields you need
        }
      })
      .sort({ createdAt: -1 })
      .lean();

    // Apply pagination only if limit is specified
    if (limitNum > 0) {
      query = query.limit(limitNum).skip(skip);
    }

    const submissions = await query;

    // Get total count for pagination info (only when limit is used)
    const total = limitNum > 0 ? await WebsiteSubmission.countDocuments(filter) : submissions.length;

    res.json({
      ok: true,
      data: submissions,
      pagination: limitNum > 0 ? {
        total,
        page: pageNum,
        limit: limitNum,
        pages: Math.ceil(total / limitNum)
      } : null
    });
  } catch (err) {
    console.error("Error fetching submissions:", err);
    res.status(500).json({ ok: false, message: "Server Error" });
  }
});

// this bellow one is working and filter works but not showing vote 
// router.get("/", async (req, res) => {
//   try {
//     const { Awards, ProfileType, Tags, Colors, Category, Country } = req.query;

//     let filter = {}; // empty means "return all"

//     // Only add to filter if query param exists
//     if (Awards) filter.Awards = Awards;
//     if (ProfileType) filter.ProfileType = ProfileType;
//     if (Category) filter.Category = Category;
//     if (Country) filter.Country = Country;

//     // Tags (array filter)
//     if (Tags) {
//       const tagsArray = Tags.split(","); // e.g. "ecommerce,blog-magazine"
//       filter.Tags = { $in: tagsArray };
//     }

//     // Colors (array filter)
//     if (Colors) {
//       const colorsArray = Colors.split(","); // e.g. "red,blue"
//       filter.Colors = { $in: colorsArray };
//     }

//     // Fetch website submissions and populate the user details from 'submittedBy' field
//     const submissions = await WebsiteSubmission.find(filter)
//       .populate('submittedBy', 'name email')  // Populate user info (name and avatar) from the User schema
//       .sort({ createdAt: -1 });

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

//Note above one is working 
//above is with user schema
// Get all stored submissions
// GET /api/submissions (with optional filters)
// router.get("/", async (req, res) => {
//   try {
//     const { Awards, ProfileType, Tags, Colors, Category, Country } = req.query;

//     let filter = {}; // empty means "return all"

//     // Only add to filter if query param exists
//     if (Awards) filter.Awards = Awards;
//     if (ProfileType) filter.ProfileType = ProfileType;
//     if (Category) filter.Category = Category;
//     if (Country) filter.Country = Country;

//     // Tags (array filter)
//     if (Tags) {
//       const tagsArray = Tags.split(","); // e.g. "ecommerce,blog-magazine"
//       filter.Tags = { $in: tagsArray };
//     }

//     // Colors (array filter)
//     if (Colors) {
//       const colorsArray = Colors.split(","); // e.g. "red,blue"
//       filter.Colors = { $in: colorsArray };
//     }

//     // If no filter applied → it will just fetch all
//     const submissions = await WebsiteSubmission.find(filter).sort({ createdAt: -1 });

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

// ✅ Get website by ID
router.get("/:id", async (req, res) => {
  try {
    const { id } = req.params;

    // 1. Fetch website
    const website = await WebsiteSubmission.findById(id)
      .populate("submittedBy", "userName email profilePhoto");

    if (!website) {
      return res.status(404).json({
        success: false,
        message: "Website not found",
      });
    }

    // 2. Fetch votes
    const votes = await Vote.find({ websiteId: id })
      .populate("submittedBy", "userName email profilePhoto")
      .sort({ createdAt: -1 })
      .lean();

    // 3. Normalize votes (ALWAYS ARRAY)
    const formattedVotes = votes.map(vote => ({
      _id: vote._id,
      submittedBy: vote.submittedBy,
      design: vote.design,
      usability: vote.usability,
      creativity: vote.creativity,
      content: vote.content,
      score: vote.score,
      overAllLabel: vote.overAllLabel,
      createdAt: vote.createdAt,
    }));

    // 4. Compute stats SAFELY
    const totalVotes = formattedVotes.length;
    const averageScore =
      totalVotes > 0
        ? Number(
          (
            formattedVotes.reduce((sum, v) => sum + (v.score || 0), 0) /
            totalVotes
          ).toFixed(1)
        )
        : 0;

    // 5. Send response
    res.status(200).json({
      success: true,
      data: {
        ...website.toObject(),
        Votes: formattedVotes, // 🔥 MATCHES FRONTEND EXPECTATION
        stats: {
          totalVotes,
          averageScore,
        },
      },
    });
  } catch (error) {
    console.error("❌ Error fetching website:", error);
    res.status(500).json({
      success: false,
      message: "Server Error",
    });
  }
});


export default router;
