import axios from "axios";
import nodemailer from "nodemailer";
import logger from "../utils/logger.js";
import { ZoomMeetingModel } from "../models/zoomMeeting.model.js";

// Zoom API Configuration
const ZOOM_ACCOUNT_ID = process.env.ZOOM_ACCOUNT_ID;
const ZOOM_CLIENT_ID = process.env.ZOOM_CLIENT_ID;
const ZOOM_CLIENT_SECRET = process.env.ZOOM_CLIENT_SECRET;
const ZOOM_HOST_USER_ID = process.env.ZOOM_HOST_USER_ID || "me";

// Email Configuration
let transporter = null;
if (process.env.SMTP_HOST && process.env.SMTP_USER && process.env.SMTP_PASS) {
  try {
    transporter = nodemailer.createTransport({
      host: process.env.SMTP_HOST,
      port: parseInt(process.env.SMTP_PORT || "465"),
      secure: process.env.SMTP_PORT === "465" || process.env.SMTP_SECURE === "true",
      auth: {
        user: process.env.SMTP_USER,
        pass: process.env.SMTP_PASS,
      },
    });
    logger.info("Email transporter configured successfully");
    logger.info(`SMTP Host: ${process.env.SMTP_HOST}, Port: ${process.env.SMTP_PORT || "465"}, User: ${process.env.SMTP_USER}`);
  } catch (err) {
    logger.error("Failed to create email transporter:", err.message);
  }
} else {
  logger.warn("Email transporter not configured - missing SMTP credentials");
  logger.warn("Required: SMTP_HOST, SMTP_USER, SMTP_PASS");
}

// Helper: Resolve admin email based on source
function resolveAdminEmail(source) {
  if (source === "abitsol") {
    return "aibitsolpvt@gmail.com";
  } else if (source === "abitsoft") {
    return "aibitsolpvt@gmail.com";
  }
  // Default fallback
  return "aibitsolpvt@gmail.com";
}

// Helper: Convert a Date assumed in Asia/Karachi (UTC+5) to ISO string in UTC
function pkLocalToIsoUtc(pkYear, pkMonth, pkDay, pkHour, pkMinute = 0) {
  const utcDate = new Date(Date.UTC(pkYear, pkMonth - 1, pkDay, pkHour - 5, pkMinute, 0));
  return utcDate.toISOString();
}

// Parse date/time string from frontend (format: "YYYY-MM-DD HH:mm") to ISO string
// Assumes the date/time is in Asia/Karachi timezone
function parseDateTimeToIso(dateTimeString) {
  if (!dateTimeString) {
    throw new Error("Date/time string is required");
  }
  
  // Parse "YYYY-MM-DD HH:mm" format
  const [datePart, timePart] = dateTimeString.trim().split(" ");
  if (!datePart || !timePart) {
    throw new Error("Invalid date/time format. Expected 'YYYY-MM-DD HH:mm'");
  }
  
  const [year, month, day] = datePart.split("-").map(Number);
  const [hour, minute] = timePart.split(":").map(Number);
  
  if (!year || !month || !day || hour === undefined || minute === undefined) {
    throw new Error("Invalid date/time format. Expected 'YYYY-MM-DD HH:mm'");
  }
  
  // Create date in Asia/Karachi timezone (UTC+5)
  // Convert to UTC by subtracting 5 hours
  return pkLocalToIsoUtc(year, month, day, hour, minute);
}

// Compute next meeting start ISO based on preferred slot in Asia/Karachi
export function computeStartTimeIso(preferredMeetingTime) {
  const nowUtc = new Date();
  // Convert now to PK (UTC+5)
  const nowPk = new Date(nowUtc.getTime() + 5 * 60 * 60 * 1000);
  const y = nowPk.getUTCFullYear();
  const m = nowPk.getUTCMonth() + 1;
  const d = nowPk.getUTCDate();
  const h = nowPk.getUTCHours();

  const slots = {
    Morning: { startHour: 9, endHour: 12 }, // 9-12
    Afternoon: { startHour: 12, endHour: 17 }, // 12-5
    Evening: { startHour: 17, endHour: 20 }, // 5-8
  };

  if (!preferredMeetingTime || preferredMeetingTime.toLowerCase().startsWith("flexible")) {
    // Flexible: now + 2h (in PK), then back to UTC ISO
    const futurePk = new Date(nowPk.getTime() + 2 * 60 * 60 * 1000);
    return pkLocalToIsoUtc(
      futurePk.getUTCFullYear(),
      futurePk.getUTCMonth() + 1,
      futurePk.getUTCDate(),
      futurePk.getUTCHours(),
      futurePk.getUTCMinutes()
    );
  }

  const key = preferredMeetingTime.split(" ")[0]; // "Morning", "Afternoon", "Evening"
  const slot = slots[key];
  if (!slot) {
    // Default to Flexible if unknown
    const futurePk = new Date(nowPk.getTime() + 2 * 60 * 60 * 1000);
    return pkLocalToIsoUtc(
      futurePk.getUTCFullYear(),
      futurePk.getUTCMonth() + 1,
      futurePk.getUTCDate(),
      futurePk.getUTCHours(),
      futurePk.getUTCMinutes()
    );
  }

  // If current PK time is before slot start today, schedule today at slot start; else tomorrow at slot start
  const scheduleToday = h < slot.startHour;
  const targetDate = new Date(Date.UTC(y, m - 1, d, 0, 0, 0));
  if (!scheduleToday) {
    targetDate.setUTCDate(targetDate.getUTCDate() + 1);
  }
  const targetY = targetDate.getUTCFullYear();
  const targetM = targetDate.getUTCMonth() + 1;
  const targetD = targetDate.getUTCDate();
  return pkLocalToIsoUtc(targetY, targetM, targetD, slot.startHour, 0);
}

// Get Zoom Access Token
async function getAccessToken() {
  if (!ZOOM_ACCOUNT_ID || !ZOOM_CLIENT_ID || !ZOOM_CLIENT_SECRET) {
    logger.error("Zoom credentials missing. Please check your .env file in the Backend folder.");
    logger.error("Required variables: ZOOM_ACCOUNT_ID, ZOOM_CLIENT_ID, ZOOM_CLIENT_SECRET");
    logger.error("You can copy these from aibit_soft/.env.local to Backend/.env");
    throw new Error("Zoom credentials are not configured. Please set ZOOM_ACCOUNT_ID, ZOOM_CLIENT_ID, and ZOOM_CLIENT_SECRET environment variables in Backend/.env file. Copy these values from aibit_soft/.env.local if they're already configured there.");
  }

  const tokenResponse = await axios.post(
    `https://zoom.us/oauth/token?grant_type=account_credentials&account_id=${encodeURIComponent(ZOOM_ACCOUNT_ID)}`,
    {},
    {
      auth: {
        username: ZOOM_CLIENT_ID,
        password: ZOOM_CLIENT_SECRET,
      },
    }
  );
  return tokenResponse.data.access_token;
}

// Check for active meetings and optionally end them
async function checkAndEndActiveMeetings(hostUserId, endActiveMeetings = false) {
  try {
    const accessToken = await getAccessToken();
    const hostIdToUse = hostUserId || ZOOM_HOST_USER_ID || "me";
    
    // Get user's active meetings
    const response = await axios.get(
      `https://api.zoom.us/v2/users/${hostIdToUse}/meetings?type=live`,
      { headers: { Authorization: `Bearer ${accessToken}` } }
    );
    
    const activeMeetings = response.data.meetings || [];
    
    if (activeMeetings.length > 0) {
      logger.warn(`Host has ${activeMeetings.length} active meeting(s)`);
      
      if (endActiveMeetings) {
        // End all active meetings
        for (const meeting of activeMeetings) {
          try {
            await axios.put(
              `https://api.zoom.us/v2/meetings/${meeting.id}/status`,
              { action: "end" },
              { headers: { Authorization: `Bearer ${accessToken}` } }
            );
            logger.info(`Ended active meeting: ${meeting.topic} (ID: ${meeting.id})`);
          } catch (err) {
            logger.error(`Failed to end meeting ${meeting.id}:`, err.message);
          }
        }
      }
      
      return activeMeetings;
    }
    
    return [];
  } catch (error) {
    // If we can't check, log but don't fail
    logger.warn("Could not check for active meetings:", error.message);
    return [];
  }
}

// Create Zoom Meeting
export async function createZoomMeeting(meetingData) {
  const {
    topic,
    startTimeIso,
    durationMinutes,
    hostUserId,
    fullName,
    email,
    preferredMeetingTime,
    projectDescription,
    additionalNotes,
    meetingType = "consultation",
    attendees = [],
    source,
  } = meetingData;

  // Validate required fields
  if (!fullName || !email || !preferredMeetingTime) {
    throw new Error("Missing required fields: fullName, email, preferredMeetingTime");
  }

  // Derive meeting details if not provided
  const derivedTopic = topic || `Meeting with ${fullName}`;
  // preferredMeetingTime is now in format "YYYY-MM-DD HH:mm" from frontend
  const derivedStartIso = startTimeIso || parseDateTimeToIso(preferredMeetingTime);
  const derivedDuration =
    Number.isFinite(Number(durationMinutes)) && Number(durationMinutes) > 0
      ? Number(durationMinutes)
      : 30;

  // Get Zoom Access Token
  const accessToken = await getAccessToken();

  // Check for active meetings (warn but don't end automatically)
  const hostIdToUse = hostUserId || ZOOM_HOST_USER_ID || "me";
  const activeMeetings = await checkAndEndActiveMeetings(hostIdToUse, false);
  if (activeMeetings.length > 0) {
    logger.warn(`Warning: Host has ${activeMeetings.length} active meeting(s). Participants may see "host has another meeting in progress" error.`);
  }

  // Prepare alternative hosts from attendees if available
  let alternativeHosts = "";
  if (attendees && attendees.length > 0) {
    const attendeeEmails = attendees
      .map(a => a.email)
      .filter(Boolean)
      .slice(0, 3)
      .join(';');
    if (attendeeEmails) {
      alternativeHosts = attendeeEmails;
    }
  }

  // Create Meeting
  const meetingSettings = {
    host_video: true,
    participant_video: true,
    join_before_host: true, // Allow participants to join before host arrives
  };

  // Add alternative hosts if available
  if (alternativeHosts) {
    meetingSettings.alternative_hosts = alternativeHosts;
  }

  const zoomResponse = await axios.post(
    `https://api.zoom.us/v2/users/${hostIdToUse}/meetings`,
    {
      topic: derivedTopic,
      type: 2, // scheduled meeting
      start_time: derivedStartIso,
      duration: derivedDuration,
      timezone: "Asia/Karachi",
      settings: meetingSettings,
    },
    { headers: { Authorization: `Bearer ${accessToken}` } }
  );

  const meeting = zoomResponse.data;

  // Normalize attendees list
  const normalizedAttendees = attendees.length ? attendees : [{ name: fullName, email }];

  // Send emails if transporter is configured
  if (transporter) {
    try {
      await sendMeetingEmails({
        meeting,
        fullName,
        email,
        preferredMeetingTime,
        projectDescription,
        additionalNotes,
        normalizedAttendees,
        derivedTopic,
        derivedStartIso,
        derivedDuration,
        source,
      });
      logger.info("Email notifications sent successfully");
    } catch (emailError) {
      logger.error("Failed to send email notifications:", emailError.message);
      logger.error("Email error details:", {
        message: emailError.message,
        code: emailError.code,
        response: emailError.response?.data,
        stack: emailError.stack,
      });
      // Don't throw - meeting was created successfully, email failure is non-critical
    }
  } else {
    logger.warn("Email transporter not configured. Skipping email notifications.");
    logger.warn("To enable emails, set SMTP_HOST, SMTP_USER, and SMTP_PASS in Backend/.env");
  }

  // Save meeting to database
  try {
    const meetingData = {
      zoomMeetingId: meeting.id.toString(),
      topic: meeting.topic,
      startTime: new Date(meeting.start_time),
      duration: derivedDuration,
      timezone: meeting.timezone || "Asia/Karachi",
      joinUrl: meeting.join_url,
      startUrl: meeting.start_url,
      meetingNumber: meeting.id?.toString(),
      password: meeting.password || undefined,
      fullName,
      email,
      meetingType: meetingType || "consultation",
      preferredMeetingTime,
      projectDescription: projectDescription || undefined,
      additionalNotes: additionalNotes || undefined,
      attendees: normalizedAttendees,
      hostUserId: hostIdToUse,
      status: "Scheduled",
    };

    const savedMeeting = await ZoomMeetingModel.create(meetingData);
    logger.info(`Zoom meeting saved to database with ID: ${savedMeeting._id}`);
    
    return {
      _id: savedMeeting._id,
      zoomMeetingId: meeting.id.toString(),
      topic: meeting.topic,
      start_time: meeting.start_time,
      join_url: meeting.join_url,
      start_url: meeting.start_url,
      timezone: meeting.timezone,
      duration: derivedDuration,
      fullName,
      email,
      status: "Scheduled",
    };
  } catch (dbError) {
    logger.error("Error saving meeting to database:", dbError);
    // Still return the meeting data even if database save fails
    return {
      zoomMeetingId: meeting.id.toString(),
      topic: meeting.topic,
      start_time: meeting.start_time,
      join_url: meeting.join_url,
      timezone: meeting.timezone,
    };
  }
}

// Convert date, time, and timezone to ISO string in UTC
// Zoom API expects ISO 8601 format in UTC (YYYY-MM-DDTHH:mm:ssZ)
// The timezone field is provided separately for display purposes
function convertDateTimeToIso(date, time, timezone) {
  if (!date || !time || !timezone) {
    throw new Error("Date, time, and timezone are required");
  }
  
  // Parse the date and time
  const [year, month, day] = date.split('-').map(Number);
  const [hour, minute] = time.split(':').map(Number);
  
  // Create a date string in ISO format: YYYY-MM-DDTHH:mm:ss
  // Note: Zoom API documentation states that start_time should be in UTC
  // However, when timezone is provided, Zoom may interpret the time in that timezone
  // For accuracy, we should convert to UTC, but without a timezone library this is complex
  
  // Workaround: Create the date-time string and let Zoom handle the conversion
  // based on the timezone field. This works because Zoom's API accepts the timezone
  // and will convert accordingly.
  
  // Format: YYYY-MM-DDTHH:mm:ss (without Z, Zoom uses timezone field)
  // For production, consider using a library like date-fns-tz for proper conversion
  const isoString = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}T${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}:00`;
  
  return isoString;
}

// Create Zoom Meeting from ScheduleZoom UI format
export async function createZoomMeetingFromSchedule(scheduleData) {
  const {
    title,
    description,
    date,
    time,
    duration,
    timezone,
    participants,
    companyEmail,
    meetingType,
    waitingRoom = true,
    recordMeeting = false,
    requirePassword = false,
    autoStart = false,
    joinBeforeHost = false,
    muteUponEntry = true,
    watermark = false,
    usePersonalMeetingId = false,
    source,
  } = scheduleData;

  // Validate required fields
  if (!title || !date || !time || !duration || !timezone || !participants) {
    throw new Error("Missing required fields: title, date, time, duration, timezone, participants");
  }

  // Parse participants string (comma-separated emails)
  const participantEmails = participants
    .split(',')
    .map(email => email.trim().toLowerCase())
    .filter(Boolean);
  
  if (participantEmails.length === 0) {
    throw new Error("At least one participant email is required");
  }

  // Validate email format
  const emailRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
  const invalidEmails = participantEmails.filter(email => !emailRegex.test(email));
  if (invalidEmails.length > 0) {
    throw new Error(`Invalid email addresses: ${invalidEmails.join(', ')}`);
  }

  // Get primary participant (first email)
  const primaryEmail = participantEmails[0];
  const primaryName = primaryEmail.split('@')[0]; // Use email username as name

  // Convert date, time, and timezone to ISO format for Zoom API
  const startTimeIso = convertDateTimeToIso(date, time, timezone);

  // Get Zoom Access Token
  const accessToken = await getAccessToken();

  // Check for active meetings (warn but don't end automatically)
  const hostIdToUse = ZOOM_HOST_USER_ID || "me";
  const activeMeetings = await checkAndEndActiveMeetings(hostIdToUse, false);
  if (activeMeetings.length > 0) {
    logger.warn(`Warning: Host has ${activeMeetings.length} active meeting(s). Participants may see "host has another meeting in progress" error.`);
  }

  // Prepare alternative hosts from participant emails
  // This allows meetings to proceed even if main host is busy
  const alternativeHosts = participantEmails.slice(0, 3).join(';'); // Zoom allows up to 30 alternative hosts

  // Prepare Zoom meeting settings
  // If join_before_host is true, disable waiting room so participants can join directly
  // This prevents the "waiting for host" issue when host is already present
  const effectiveWaitingRoom = joinBeforeHost ? false : waitingRoom;
  
  const zoomSettings = {
    host_video: true,
    participant_video: true,
    join_before_host: joinBeforeHost,
    mute_upon_entry: muteUponEntry,
    waiting_room: effectiveWaitingRoom,
    watermark: watermark,
    use_pmi: usePersonalMeetingId,
    approval_type: effectiveWaitingRoom ? 1 : 0, // 0 = Automatically approve, 1 = Manually approve
    audio: "both", // both, telephony, voip
    auto_recording: recordMeeting ? "cloud" : "none", // none, local, cloud
    alternative_hosts: alternativeHosts, // Add alternative hosts so meetings can proceed without main host
  };

  // Add password if required
  if (requirePassword) {
    // Zoom will generate a password automatically if not provided
    // We can set it in settings
    zoomSettings.meeting_authentication = false; // Set to true if you want to require authentication
  }

  // Create Meeting
  const zoomResponse = await axios.post(
    `https://api.zoom.us/v2/users/${hostIdToUse}/meetings`,
    {
      topic: title,
      type: 2, // scheduled meeting
      start_time: startTimeIso,
      duration: duration,
      timezone: timezone,
      agenda: description || undefined,
      settings: zoomSettings,
    },
    { headers: { Authorization: `Bearer ${accessToken}` } }
  );

  const meeting = zoomResponse.data;

  // Prepare attendees array for database
  const attendees = participantEmails.map(email => ({
    name: email.split('@')[0],
    email: email,
  }));

  // Add company email if provided
  if (companyEmail && !participantEmails.includes(companyEmail.toLowerCase().trim())) {
    attendees.push({
      name: companyEmail.split('@')[0],
      email: companyEmail.toLowerCase().trim(),
    });
  }

  // Send emails if transporter is configured
  if (transporter) {
    try {
      await sendScheduleZoomEmails({
        meeting,
        title,
        description,
        date,
        time,
        duration,
        timezone,
        participantEmails,
        companyEmail,
        meetingType,
        source,
      });
      logger.info("Email notifications sent successfully");
    } catch (emailError) {
      logger.error("Failed to send email notifications:", emailError.message);
      // Don't throw - meeting was created successfully, email failure is non-critical
    }
  } else {
    logger.warn("Email transporter not configured. Skipping email notifications.");
  }

  // Save meeting to database
  try {
    const meetingData = {
      zoomMeetingId: meeting.id.toString(),
      topic: meeting.topic || title,
      startTime: new Date(meeting.start_time),
      duration: duration,
      timezone: meeting.timezone || timezone,
      joinUrl: meeting.join_url,
      startUrl: meeting.start_url,
      meetingNumber: meeting.id?.toString(),
      password: meeting.password || undefined,
      fullName: primaryName,
      email: primaryEmail,
      meetingType: meetingType || "consultation",
      preferredMeetingTime: `${date} ${time}`,
      projectDescription: description || undefined,
      additionalNotes: undefined,
      attendees: attendees,
      hostUserId: hostIdToUse,
      status: "Scheduled",
    };

    const savedMeeting = await ZoomMeetingModel.create(meetingData);
    logger.info(`Zoom meeting saved to database with ID: ${savedMeeting._id}`);
    
    return {
      _id: savedMeeting._id,
      zoomMeetingId: meeting.id.toString(),
      topic: meeting.topic || title,
      start_time: meeting.start_time,
      join_url: meeting.join_url,
      start_url: meeting.start_url,
      timezone: meeting.timezone || timezone,
      duration: duration,
      password: meeting.password,
      meeting_number: meeting.id?.toString(),
      participants: participantEmails,
      companyEmail: companyEmail,
      status: "Scheduled",
    };
  } catch (dbError) {
    logger.error("Error saving meeting to database:", dbError);
    // Still return the meeting data even if database save fails
    return {
      zoomMeetingId: meeting.id.toString(),
      topic: meeting.topic || title,
      start_time: meeting.start_time,
      join_url: meeting.join_url,
      start_url: meeting.start_url,
      timezone: meeting.timezone || timezone,
      duration: duration,
      password: meeting.password,
      meeting_number: meeting.id?.toString(),
      participants: participantEmails,
    };
  }
}

// Send emails for ScheduleZoom meetings
async function sendScheduleZoomEmails({
  meeting,
  title,
  description,
  date,
  time,
  duration,
  timezone,
  participantEmails,
  companyEmail,
  meetingType,
  source,
}) {
  const adminEmail = resolveAdminEmail(source);
  const companyEmailToUse = companyEmail || process.env.COMPANY_EMAIL || "contact@aibitsoft.com";

  // Format date and time for display
  const meetingDate = new Date(`${date}T${time}`);
  const formattedDate = meetingDate.toLocaleDateString('en-US', {
    weekday: 'long',
    year: 'numeric',
    month: 'long',
    day: 'numeric',
    timeZone: timezone,
  });
  
  const formattedTime = meetingDate.toLocaleTimeString('en-US', {
    hour: '2-digit',
    minute: '2-digit',
    hour12: true,
    timeZone: timezone,
  });

  // Admin Email HTML
  const adminEmailHTML = `
<div style="font-family: system-ui, sans-serif, Arial; font-size: 15px; color: #333; padding: 14px 8px; background-color: #f5f5f5;">
  <div style="max-width: 600px; margin: auto; background-color: #fff; border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); overflow: hidden;">
    <div style="border-top: 6px solid #007bff; padding: 16px;">
      <span style="font-size: 18px; font-weight: 600; color: #007bff;">New Zoom Meeting Scheduled</span>
    </div>
    <div style="padding: 24px 16px;">
      <p><strong>Meeting Title:</strong> ${title}</p>
      <p><strong>Participants:</strong> ${participantEmails.join(", ")}</p>
      ${companyEmailToUse ? `<p><strong>Company Email:</strong> ${companyEmailToUse}</p>` : ''}
      <div style="margin: 14px 0;">
        <p style="margin: 0 0 6px 0;"><strong>Date:</strong> ${formattedDate}</p>
        <p style="margin: 0 0 6px 0;"><strong>Time:</strong> ${formattedTime} (${timezone})</p>
        <p style="margin: 0 0 6px 0;"><strong>Duration:</strong> ${duration} minutes</p>
        ${description ? `<p style="margin: 10px 0 6px 0;"><strong>Description:</strong></p>
        <div style="white-space: pre-wrap; border: 1px solid #eee; background: #fafafa; padding: 10px; border-radius: 6px;">${description}</div>` : ''}
      </div>
      <div style="background-color: #f0f6ff; border: 1px solid #d6e4ff; border-radius: 6px; padding: 16px; margin: 20px 0;">
        <p style="margin: 0 0 8px 0;"><strong>📅 Topic:</strong> ${title}</p>
        <p style="margin: 0 0 8px 0;">
          <strong>🕒 Start Time:</strong> ${formattedDate} at ${formattedTime} (${timezone})
        </p>
        <p style="margin: 0 0 8px 0;">
          <strong>🎥 Host Link:</strong>
          <a href="${meeting.start_url}" style="color: #007bff; text-decoration: none;">Start Meeting</a>
        </p>
        <p style="margin: 0;">
          <strong>💻 Join Link:</strong>
          <a href="${meeting.join_url}" style="color: #007bff; text-decoration: none;">Join Meeting</a>
        </p>
        ${meeting.password ? `<p style="margin: 8px 0 0 0;"><strong>🔐 Password:</strong> ${meeting.password}</p>` : ''}
      </div>
    </div>
  </div>
</div>`;

  // Send admin email
  if (adminEmail) {
    try {
      // Use contact@aibitsol.com when source is "abitsol", otherwise use contact@aibitsoft.com
      const fromEmail = source === "abitsol" ? "contact@aibitsol.com" : "contact@aibitsoft.com";
      logger.info(`Sending admin email - source: ${source}, from: ${fromEmail}, to: ${adminEmail}`);
      await transporter.sendMail({
        from: `"Zoom Meeting Scheduler" <${fromEmail}>`,
        to: adminEmail,
        replyTo: participantEmails[0],
        subject: `New Zoom Meeting Scheduled: ${title}`,
        html: adminEmailHTML,
      });
      logger.info(`Admin email sent successfully to: ${adminEmail}`);
    } catch (err) {
      logger.error("Failed to send admin email:", err.message);
    }
  }

  // User Confirmation Email HTML
  const userEmailHTML = `
<div style="font-family: system-ui, sans-serif, Arial; font-size: 15px; color: #333; padding: 14px 8px; background-color: #f5f5f5;">
  <div style="max-width: 600px; margin: auto; background-color: #fff; border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); overflow: hidden;">
    <div style="border-top: 6px solid #007bff; padding: 16px;">
      <span style="font-size: 18px; font-weight: 600; color: #007bff;">Your Zoom Meeting Confirmation</span>
    </div>
    <div style="padding: 24px 16px;">
      <p>Hello,</p>
      <p>Your Zoom meeting has been successfully scheduled! Here are the details:</p>
      <div style="background-color: #f0f6ff; border: 1px solid #d6e4ff; border-radius: 6px; padding: 16px; margin: 20px 0;">
        <p style="margin: 0 0 8px 0;"><strong>📅 Topic:</strong> ${title}</p>
        <p style="margin: 0 0 8px 0;">
          <strong>🕒 Start Time:</strong> ${formattedDate} at ${formattedTime} (${timezone})
        </p>
        <p style="margin: 0 0 8px 0;"><strong>⏱️ Duration:</strong> ${duration} minutes</p>
        ${description ? `<p style="margin: 8px 0 0 0;"><strong>📝 Description:</strong><br/>${description}</p>` : ""}
      </div>
      <div style="text-align: center; margin: 24px 0;">
        <a href="${meeting.join_url}" style="background-color: #007bff; color: #fff; text-decoration: none; padding: 12px 24px; border-radius: 6px; display: inline-block; font-weight: 600; font-size: 16px;">Join Meeting</a>
      </div>
      <p style="color: #666; font-size: 13px; margin-top: 16px;">
        <strong>Meeting Link:</strong><br/>
        <a href="${meeting.join_url}" style="color: #007bff; word-break: break-all;">${meeting.join_url}</a>
      </p>
      ${meeting.password ? `<p style="color: #666; font-size: 13px; margin-top: 8px;"><strong>Meeting Password:</strong> ${meeting.password}</p>` : ''}
      <p style="margin-top: 24px;">
        We look forward to speaking with you!<br />
        <strong>Zoom Meeting Scheduler Team</strong><br />
        <span style="color: #888;">${companyEmailToUse}</span>
      </p>
    </div>
  </div>
</div>`;

  // Send email to all participants
  // Use contact@aibitsol.com when source is "abitsol", otherwise use contact@aibitsoft.com
  const fromEmail = source === "abitsol" ? "contact@aibitsol.com" : "contact@aibitsoft.com";
  for (const email of participantEmails) {
    try {
      logger.info(`Sending user email - source: ${source}, from: ${fromEmail}, to: ${email}`);
      await transporter.sendMail({
        from: `"Zoom Meeting Scheduler" <${fromEmail}>`,
        to: email,
        replyTo: companyEmailToUse,
        subject: `Your Zoom Meeting Confirmation - ${title}`,
        html: userEmailHTML,
      });
      logger.info(`User confirmation email sent successfully to: ${email}`);
    } catch (err) {
      logger.error(`Failed to send email to ${email}:`, err.message);
    }
  }
}

// List all zoom meetings
export async function listZoomMeetings(filters = {}) {
  try {
    const query = {};
    
    if (filters.status) {
      query.status = filters.status;
    }
    
    if (filters.email) {
      query.email = filters.email.toLowerCase();
    }
    
    if (filters.startDate || filters.endDate) {
      query.startTime = {};
      if (filters.startDate) {
        query.startTime.$gte = new Date(filters.startDate);
      }
      if (filters.endDate) {
        query.startTime.$lte = new Date(filters.endDate);
      }
    }
    
    const items = await ZoomMeetingModel.find(query)
      .sort({ startTime: -1 })
      .lean();
    return items;
  } catch (error) {
    logger.error("Error in listZoomMeetings service:", error);
    throw error;
  }
}

// Get zoom meeting by ID
export async function getZoomMeetingById(id) {
  try {
    if (!id) {
      throw new Error("Meeting ID is required");
    }
    const item = await ZoomMeetingModel.findById(id).lean();
    return item || null;
  } catch (error) {
    logger.error("Error in getZoomMeetingById service:", error);
    throw error;
  }
}

// Get zoom meeting by Zoom Meeting ID
export async function getZoomMeetingByZoomId(zoomMeetingId) {
  try {
    if (!zoomMeetingId) {
      throw new Error("Zoom Meeting ID is required");
    }
    const item = await ZoomMeetingModel.findOne({ zoomMeetingId }).lean();
    return item || null;
  } catch (error) {
    logger.error("Error in getZoomMeetingByZoomId service:", error);
    throw error;
  }
}

// Update zoom meeting
export async function updateZoomMeeting(id, data) {
  try {
    if (!id) {
      throw new Error("Meeting ID is required");
    }
    const updated = await ZoomMeetingModel.findByIdAndUpdate(
      id,
      { $set: data },
      { new: true, runValidators: true }
    ).lean();
    return updated || null;
  } catch (error) {
    logger.error("Error in updateZoomMeeting service:", error);
    throw error;
  }
}

// Delete zoom meeting
export async function deleteZoomMeeting(id) {
  try {
    if (!id) {
      throw new Error("Meeting ID is required");
    }
    const res = await ZoomMeetingModel.findByIdAndDelete(id).lean();
    return !!res;
  } catch (error) {
    logger.error("Error in deleteZoomMeeting service:", error);
    throw error;
  }
}

// Cancel zoom meeting (updates status and optionally deletes from Zoom)
export async function cancelZoomMeeting(id, deleteFromZoom = false) {
  try {
    if (!id) {
      throw new Error("Meeting ID is required");
    }
    
    const meeting = await ZoomMeetingModel.findById(id);
    if (!meeting) {
      throw new Error("Meeting not found");
    }
    
    // Update status to Cancelled
    meeting.status = "Cancelled";
    await meeting.save();
    
    // Optionally delete from Zoom
    if (deleteFromZoom && meeting.zoomMeetingId) {
      try {
        const accessToken = await getAccessToken();
        await axios.delete(
          `https://api.zoom.us/v2/meetings/${meeting.zoomMeetingId}`,
          { headers: { Authorization: `Bearer ${accessToken}` } }
        );
        logger.info(`Meeting ${meeting.zoomMeetingId} deleted from Zoom`);
      } catch (zoomError) {
        logger.error("Error deleting meeting from Zoom:", zoomError.message);
        // Don't throw - we've already updated the status
      }
    }
    
    return meeting.toObject();
  } catch (error) {
    logger.error("Error in cancelZoomMeeting service:", error);
    throw error;
  }
}

// Send meeting emails
async function sendMeetingEmails({
  meeting,
  fullName,
  email,
  preferredMeetingTime,
  projectDescription,
  additionalNotes,
  normalizedAttendees,
  derivedTopic,
  derivedStartIso,
  derivedDuration,
  source,
}) {
  const adminEmail = resolveAdminEmail(source);
  const companyEmail = process.env.COMPANY_EMAIL || "contact@aibitsoft.com";

  // Admin Email HTML
  const adminEmailHTML = `
<div style="font-family: system-ui, sans-serif, Arial; font-size: 15px; color: #333; padding: 14px 8px; background-color: #f5f5f5;">
  <div style="max-width: 600px; margin: auto; background-color: #fff; border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); overflow: hidden;">
    <div style="border-top: 6px solid #007bff; padding: 16px;">
      <span style="font-size: 18px; font-weight: 600; color: #007bff;">New Meeting Scheduled</span>
    </div>
    <div style="padding: 24px 16px;">
      <p><strong>Client Name:</strong> ${fullName || normalizedAttendees[0]?.name || "N/A"}</p>
      <p><strong>Email(s):</strong> ${normalizedAttendees.map((a) => a.email).join(", ")}</p>
      <div style="margin: 14px 0;">
        <p style="margin: 0 0 6px 0;"><strong>Preferred Meeting Time:</strong> ${preferredMeetingTime || "N/A"}</p>
        <p style="margin: 0 0 6px 0;"><strong>Project Description:</strong></p>
        <div style="white-space: pre-wrap; border: 1px solid #eee; background: #fafafa; padding: 10px; border-radius: 6px;">${projectDescription || "N/A"}</div>
        <p style="margin: 10px 0 6px 0;"><strong>Additional Notes:</strong></p>
        <div style="white-space: pre-wrap; border: 1px solid #eee; background: #fafafa; padding: 10px; border-radius: 6px;">${additionalNotes || "None"}</div>
      </div>
      <div style="background-color: #f0f6ff; border: 1px solid #d6e4ff; border-radius: 6px; padding: 16px; margin: 20px 0;">
        <p style="margin: 0 0 8px 0;"><strong>📅 Topic:</strong> ${derivedTopic}</p>
        <p style="margin: 0 0 8px 0;">
          <strong>🕒 Start Time:</strong> ${new Date(derivedStartIso).toLocaleString("en-PK", {
            timeZone: "Asia/Karachi",
            hour12: true,
            year: "numeric",
            month: "long",
            day: "numeric",
            hour: "2-digit",
            minute: "2-digit",
          })}
        </p>
        <p style="margin: 0 0 8px 0;">
          <strong>🎥 Host Link:</strong>
          <a href="${meeting.start_url}" style="color: #007bff; text-decoration: none;">Start Meeting</a>
        </p>
        <p style="margin: 0;">
          <strong>💻 Client Join Link:</strong>
          <a href="${meeting.join_url}" style="color: #007bff; text-decoration: none;">Join Meeting</a>
        </p>
      </div>
    </div>
  </div>
</div>`;

  // Send admin email
  if (adminEmail) {
    try {
      // Use contact@aibitsol.com when source is "abitsol", otherwise use contact@aibitsoft.com
      const fromEmail = source === "abitsol" ? "contact@aibitsol.com" : "contact@aibitsoft.com";
      logger.info(`Sending admin email - source: ${source}, from: ${fromEmail}, to: ${adminEmail}`);
      await transporter.sendMail({
        from: `"Zoom Meeting Scheduler" <${fromEmail}>`,
        to: adminEmail,
        replyTo: email || normalizedAttendees[0]?.email,
        subject: `New Meeting Scheduled: Zoom Meeting`,
        html: adminEmailHTML,
      });
      logger.info(`Admin email sent successfully to: ${adminEmail}`);
    } catch (err) {
      logger.error("Failed to send admin email:", err.message);
      logger.error("Admin email error details:", {
        message: err.message,
        code: err.code,
        response: err.response?.data,
        command: err.command,
      });
      throw err; // Re-throw to be caught by outer try-catch
    }
  }

  // User Confirmation Email HTML
  const userEmailHTML = `
<div style="font-family: system-ui, sans-serif, Arial; font-size: 15px; color: #333; padding: 14px 8px; background-color: #f5f5f5;">
  <div style="max-width: 600px; margin: auto; background-color: #fff; border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); overflow: hidden;">
    <div style="border-top: 6px solid #007bff; padding: 16px;">
      <span style="font-size: 18px; font-weight: 600; color: #007bff;">Your Meeting Confirmation</span>
    </div>
    <div style="padding: 24px 16px;">
      <p>Hi ${fullName || "there"},</p>
      <p>Your meeting has been successfully scheduled! Here are the details:</p>
      <div style="background-color: #f0f6ff; border: 1px solid #d6e4ff; border-radius: 6px; padding: 16px; margin: 20px 0;">
        <p style="margin: 0 0 8px 0;"><strong>📅 Topic:</strong> ${derivedTopic}</p>
        <p style="margin: 0 0 8px 0;">
          <strong>🕒 Start Time:</strong> ${new Date(derivedStartIso).toLocaleString("en-PK", {
            timeZone: "Asia/Karachi",
            hour12: true,
            year: "numeric",
            month: "long",
            day: "numeric",
            hour: "2-digit",
            minute: "2-digit",
          })}
        </p>
        <p style="margin: 0 0 8px 0;"><strong>⏱️ Duration:</strong> ${derivedDuration} minutes</p>
        ${projectDescription ? `<p style="margin: 8px 0 0 0;"><strong>📝 Project Description:</strong><br/>${projectDescription}</p>` : ""}
      </div>
      <div style="text-align: center; margin: 24px 0;">
        <a href="${meeting.join_url}" style="background-color: #007bff; color: #fff; text-decoration: none; padding: 12px 24px; border-radius: 6px; display: inline-block; font-weight: 600; font-size: 16px;">Join Meeting</a>
      </div>
      <p style="color: #666; font-size: 13px; margin-top: 16px;">
        <strong>Meeting Link:</strong><br/>
        <a href="${meeting.join_url}" style="color: #007bff; word-break: break-all;">${meeting.join_url}</a>
      </p>
      ${additionalNotes ? `<p style="margin-top: 16px;"><strong>Additional Notes:</strong><br/>${additionalNotes}</p>` : ""}
      <p style="margin-top: 24px;">
        We look forward to speaking with you!<br />
        <strong>Consultation Scheduler Team</strong><br />
        <span style="color: #888;">${companyEmail}</span>
      </p>
    </div>
  </div>
</div>`;

  // Send user email
  const userEmail = email || normalizedAttendees[0]?.email;
  if (userEmail) {
    try {
      // Use contact@aibitsol.com when source is "abitsol", otherwise use contact@aibitsoft.com
      const fromEmail = source === "abitsol" ? "contact@aibitsol.com" : "contact@aibitsoft.com";
      logger.info(`Sending user email - source: ${source}, from: ${fromEmail}, to: ${userEmail}`);
      await transporter.sendMail({
        from: `"Zoom Meeting Scheduler" <${fromEmail}>`,
        to: userEmail,
        replyTo: companyEmail,
        subject: `Your Meeting Confirmation - ${derivedTopic}`,
        html: userEmailHTML,
      });
      logger.info(`User confirmation email sent successfully to: ${userEmail}`);
    } catch (err) {
      logger.error("Failed to send user confirmation email:", err.message);
      logger.error("User email error details:", {
        message: err.message,
        code: err.code,
        response: err.response?.data,
        command: err.command,
        to: userEmail,
      });
      throw err; // Re-throw to be caught by outer try-catch
    }
  } else {
    logger.warn("No user email provided, skipping user confirmation email");
  }
}

