import axios from "axios";
import nodemailer from "nodemailer";
import logger from "../utils/logger.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: 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();
}

// 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;
}

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

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

  // Derive meeting details if not provided
  const derivedTopic = topic || `${meetingType} - ${fullName}`;
  const derivedStartIso = startTimeIso || computeStartTimeIso(preferredMeetingTime);
  const derivedDuration =
    Number.isFinite(Number(durationMinutes)) && Number(durationMinutes) > 0
      ? Number(durationMinutes)
      : 30;

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

  // Create Meeting
  const hostIdToUse = hostUserId || ZOOM_HOST_USER_ID || "me";
  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: {
        host_video: true,
        participant_video: true,
        join_before_host: false,
      },
    },
    { 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,
        meetingType,
        preferredMeetingTime,
        projectDescription,
        additionalNotes,
        normalizedAttendees,
        derivedTopic,
        derivedStartIso,
        derivedDuration,
      });
      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");
  }

  return {
    topic: meeting.topic,
    start_time: meeting.start_time,
    join_url: meeting.join_url,
    timezone: meeting.timezone,
  };
}

// Send meeting emails
async function sendMeetingEmails({
  meeting,
  fullName,
  email,
  meetingType,
  preferredMeetingTime,
  projectDescription,
  additionalNotes,
  normalizedAttendees,
  derivedTopic,
  derivedStartIso,
  derivedDuration,
}) {
  const adminEmail = process.env.ADMIN_EMAIL;
  const companyEmail = process.env.COMPANY_EMAIL || adminEmail || process.env.SMTP_USER;

  // 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>Meeting Type:</strong> ${meetingType || "N/A"}</p>
        <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 {
      await transporter.sendMail({
        from: `"Zoom Meeting Scheduler" <${process.env.SMTP_USER}>`,
        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>
        ${meetingType ? `<p style="margin: 0 0 8px 0;"><strong>📋 Meeting Type:</strong> ${meetingType}</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 {
      await transporter.sendMail({
        from: `"Zoom Meeting Scheduler" <${process.env.SMTP_USER}>`,
        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");
  }
}

