import { createUserResumeSchema } from "../models/userResume.schema.js";
import { UserResumeModel } from "../models/userResume.model.js";
import { createUserResume, listUserResumes } from "../services/userResume.service.js";
import { uploadToCloudinary } from "../utils/cloudinary.js";
import { successResponse, errorResponse } from "../utils/response.js";
import { HTTP_STATUS } from "../constants/index.js";
import logger from "../utils/logger.js";
import { join, dirname } from "path";
import { fileURLToPath } from "url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

export const list = async (req, res, next) => {
  try {
    const filters = {};
    
    // Optional query parameters
    if (req.query.email) {
      filters.email = req.query.email;
    }
    if (req.query.jobId) {
      filters.jobId = req.query.jobId;
    }

    logger.info("Fetching user resumes with filters:", JSON.stringify(filters));
    
    // Get database info before querying
    const dbName = UserResumeModel.db?.databaseName || 'unknown';
    const collectionName = UserResumeModel.collection?.collectionName || 'unknown';
    const connectionState = UserResumeModel.db?.readyState || 'unknown';
    
    logger.info(`Database: ${dbName}`);
    logger.info(`Collection: ${collectionName}`);
    logger.info(`Connection State: ${connectionState} (0=disconnected, 1=connected, 2=connecting, 3=disconnecting)`);
    
    const items = await listUserResumes(filters);
    logger.info(`Retrieved ${items.length} user resumes from database`);
    
    // Get total count for diagnostic purposes
    let totalCount = 0;
    try {
      totalCount = await UserResumeModel.countDocuments({});
      logger.info(`Total documents in collection: ${totalCount}`);
    } catch (countError) {
      logger.error("Error counting documents:", countError);
    }
    
    if (items.length === 0) {
      logger.warn("No user resumes found in database. This might indicate:");
      logger.warn("1. The collection is empty");
      logger.warn("2. The collection name might be different");
      logger.warn("3. The database connection might be pointing to a different database");
      logger.warn(`Current database: ${dbName}, Collection: ${collectionName}, Total count: ${totalCount}`);
    }
    
    return successResponse(res, items, HTTP_STATUS.OK);
  } catch (err) {
    logger.error("Error listing user resumes:", err);
    logger.error("Error details:", {
      message: err.message,
      stack: err.stack,
      name: err.name
    });
    next(err);
  }
};

export const create = async (req, res, next) => {
  try {
    logger.info("Received request to create user resume");
    logger.info("Request body:", req.body);
    logger.info("Request file:", req.file ? { 
      filename: req.file.filename, 
      path: req.file.path, 
      size: req.file.size,
      mimetype: req.file.mimetype
    } : "No file");
    
    // Check if file was uploaded
    if (!req.file) {
      logger.warn("No file uploaded in request");
      return errorResponse(res, "CV file is required", HTTP_STATUS.BAD_REQUEST);
    }

    // Handle multer errors
    if (req.fileValidationError) {
      // Delete uploaded file if validation fails
      if (req.file) {
        const { unlink } = await import("fs/promises");
        try {
          await unlink(req.file.path);
        } catch (err) {
          logger.warn("Failed to delete file after validation error:", err);
        }
      }
      return errorResponse(res, req.fileValidationError, HTTP_STATUS.BAD_REQUEST);
    }

    // Get form data
    const { fullName, email, phoneNumber, coverNote, jobId, positionTitle } = req.body;

    if (!fullName || !email || !phoneNumber) {
      // Delete uploaded file if validation fails
      if (req.file) {
        const { unlink } = await import("fs/promises");
        try {
          await unlink(req.file.path);
        } catch (err) {
          logger.warn("Failed to delete file after validation error:", err);
        }
      }
      return errorResponse(
        res,
        "Full name, email, and phone number are required",
        HTTP_STATUS.BAD_REQUEST
      );
    }

    // Upload file to Cloudinary
    let cvURL;
    try {
      const filePath = req.file.path;
      logger.info(`Attempting to upload file: ${filePath}`);
      logger.info(`File exists: ${req.file ? 'Yes' : 'No'}, File path: ${req.file?.path}`);
      
      cvURL = await uploadToCloudinary(filePath, "user-resumes");
      logger.info(`Successfully uploaded to Cloudinary: ${cvURL}`);
    } catch (cloudinaryError) {
      logger.error("Cloudinary upload error:", cloudinaryError);
      logger.error("Error details:", {
        message: cloudinaryError?.message,
        stack: cloudinaryError?.stack,
        name: cloudinaryError?.name
      });
      
      // Delete local file if Cloudinary upload fails
      if (req.file && req.file.path) {
        const { unlink } = await import("fs/promises");
        try {
          await unlink(req.file.path);
          logger.info(`Deleted local file after Cloudinary error: ${req.file.path}`);
        } catch (err) {
          logger.warn("Failed to delete file after Cloudinary error:", err);
        }
      }
      
      // Provide more specific error message
      const errorMessage = cloudinaryError?.message || "Failed to upload CV. Please try again.";
      return errorResponse(
        res,
        errorMessage.includes("credentials") 
          ? "Cloudinary is not configured. Please contact administrator."
          : errorMessage,
        HTTP_STATUS.INTERNAL_SERVER_ERROR
      );
    }

    // Prepare data for database
    const resumeData = {
      fullName: fullName.trim(),
      email: email.trim().toLowerCase(),
      phoneNumber: phoneNumber.trim(),
      cvURL: cvURL,
      coverNote: coverNote ? coverNote.trim() : undefined,
      jobId: jobId || undefined,
      positionTitle: positionTitle ? positionTitle.trim() : undefined,
    };

    // Validate data
    const parsed = createUserResumeSchema.safeParse(resumeData);
    if (!parsed.success) {
      return errorResponse(
        res,
        "Validation failed",
        HTTP_STATUS.BAD_REQUEST,
        parsed.error.flatten()
      );
    }

    // Save to database
    const created = await createUserResume(parsed.data);
    logger.info(`User resume created with ID: ${created._id}`);

    return successResponse(res, created, HTTP_STATUS.CREATED);
  } catch (err) {
    logger.error("Error creating user resume:", err);
    logger.error("Error stack:", err?.stack);
    logger.error("Error name:", err?.name);
    logger.error("Error message:", err?.message);
    
    // Clean up file if something went wrong
    if (req.file && req.file.path) {
      const { unlink } = await import("fs/promises");
      try {
        await unlink(req.file.path);
        logger.info(`Deleted local file after error: ${req.file.path}`);
      } catch (deleteError) {
        logger.warn("Failed to delete file after error:", deleteError);
      }
    }
    
    // Don't expose internal errors to client, but log them
    const errorMessage = err?.message || "An unexpected error occurred";
    return errorResponse(
      res,
      errorMessage.includes("E11000") 
        ? "An application with this email already exists."
        : "Failed to submit application. Please try again.",
      HTTP_STATUS.INTERNAL_SERVER_ERROR
    );
  }
};

