import {
  createZoomMeeting,
  createZoomMeetingFromSchedule,
  listZoomMeetings,
  getZoomMeetingById,
  getZoomMeetingByZoomId,
  updateZoomMeeting,
  deleteZoomMeeting,
  cancelZoomMeeting,
} from "../services/zoomMeeting.service.js";
import {
  createZoomMeetingSchema,
  updateZoomMeetingSchema,
  normalizeZoomMeetingPayload,
  scheduleZoomMeetingSchema,
  normalizeScheduleZoomPayload,
} from "../models/zoomMeeting.schema.js";
import { successResponse, errorResponse } from "../utils/response.js";
import { HTTP_STATUS } from "../constants/index.js";
import logger from "../utils/logger.js";

export const create = async (req, res, next) => {
  try {
    const normalized = normalizeZoomMeetingPayload(req.body);
    
    // Detect source from request if not provided
    if (!normalized.source) {
      const origin = req.headers.origin || req.headers.referer || "";
      if (origin.includes("aibitsoft.com")) {
        normalized.source = "abitsoft";
      } else if (origin.includes("aibitsol.com")) {
        normalized.source = "abitsol";
      } else {
        normalized.source = "abitsol"; // Default
      }
    }
    
    const parsed = createZoomMeetingSchema.safeParse(normalized);
    
    if (!parsed.success) {
      // Format validation errors for better readability
      const formattedErrors = parsed.error.flatten();
      const errorMessages = Object.entries(formattedErrors.fieldErrors || {})
        .map(([field, errors]) => `${field}: ${Array.isArray(errors) ? errors.join(', ') : errors}`)
        .join('; ');
      
      logger.warn("Validation failed:", formattedErrors);
      logger.warn("Request body:", req.body);
      
      // Return error in the format expected by the frontend (with ok: false)
      return res.status(HTTP_STATUS.BAD_REQUEST).json({
        ok: false,
        error: `Validation failed: ${errorMessages || 'Invalid input data'}`,
        errors: formattedErrors,
      });
    }

    const meeting = await createZoomMeeting(parsed.data);

    logger.info(`Zoom meeting created: ${meeting.topic}`);

    // Return response in the format expected by the frontend
    return res.status(200).json({
      ok: true,
      meeting,
      message: "Meeting created. Admin and user notified via email.",
    });
  } catch (err) {
    logger.error("Error creating Zoom meeting:", err);
    
    // Return error in the format expected by the frontend
    return res.status(500).json({
      ok: false,
      error: err.response?.data?.message || err.message || "Failed to create meeting",
    });
  }
};

export const list = async (req, res, next) => {
  try {
    const filters = {
      status: req.query.status,
      email: req.query.email,
      startDate: req.query.startDate,
      endDate: req.query.endDate,
    };
    const items = await listZoomMeetings(filters);
    return successResponse(res, items, HTTP_STATUS.OK);
  } catch (err) {
    logger.error("Error listing zoom meetings:", err);
    next(err);
  }
};

export const getById = async (req, res, next) => {
  try {
    const { id } = req.params;
    if (!id) {
      return errorResponse(res, "Meeting ID is required", HTTP_STATUS.BAD_REQUEST);
    }
    const item = await getZoomMeetingById(id);
    if (!item) {
      return errorResponse(res, "Meeting not found", HTTP_STATUS.NOT_FOUND);
    }
    return successResponse(res, item, HTTP_STATUS.OK);
  } catch (err) {
    logger.error("Error getting zoom meeting by ID:", err);
    next(err);
  }
};

export const getByZoomId = async (req, res, next) => {
  try {
    const { zoomId } = req.params;
    if (!zoomId) {
      return errorResponse(res, "Zoom Meeting ID is required", HTTP_STATUS.BAD_REQUEST);
    }
    const item = await getZoomMeetingByZoomId(zoomId);
    if (!item) {
      return errorResponse(res, "Meeting not found", HTTP_STATUS.NOT_FOUND);
    }
    return successResponse(res, item, HTTP_STATUS.OK);
  } catch (err) {
    logger.error("Error getting zoom meeting by Zoom ID:", err);
    next(err);
  }
};

export const update = async (req, res, next) => {
  try {
    const { id } = req.params;
    if (!id) {
      return errorResponse(res, "Meeting ID is required", HTTP_STATUS.BAD_REQUEST);
    }
    const normalized = normalizeZoomMeetingPayload(req.body);
    const parsed = updateZoomMeetingSchema.safeParse(normalized);
    
    if (!parsed.success) {
      return errorResponse(
        res,
        "Validation failed",
        HTTP_STATUS.BAD_REQUEST,
        parsed.error.flatten()
      );
    }
    
    const updated = await updateZoomMeeting(id, parsed.data);
    if (!updated) {
      return errorResponse(res, "Meeting not found", HTTP_STATUS.NOT_FOUND);
    }
    logger.info(`Zoom meeting updated with ID: ${id}`);
    return successResponse(res, updated, HTTP_STATUS.OK);
  } catch (err) {
    logger.error("Error updating zoom meeting:", err);
    next(err);
  }
};

export const remove = async (req, res, next) => {
  try {
    const { id } = req.params;
    if (!id) {
      return errorResponse(res, "Meeting ID is required", HTTP_STATUS.BAD_REQUEST);
    }
    const ok = await deleteZoomMeeting(id);
    if (!ok) {
      return errorResponse(res, "Meeting not found", HTTP_STATUS.NOT_FOUND);
    }
    logger.info(`Zoom meeting deleted with ID: ${id}`);
    return res.status(HTTP_STATUS.NO_CONTENT).send();
  } catch (err) {
    logger.error("Error deleting zoom meeting:", err);
    next(err);
  }
};

export const cancel = async (req, res, next) => {
  try {
    const { id } = req.params;
    if (!id) {
      return errorResponse(res, "Meeting ID is required", HTTP_STATUS.BAD_REQUEST);
    }
    const deleteFromZoom = req.query.deleteFromZoom === "true";
    const cancelled = await cancelZoomMeeting(id, deleteFromZoom);
    if (!cancelled) {
      return errorResponse(res, "Meeting not found", HTTP_STATUS.NOT_FOUND);
    }
    logger.info(`Zoom meeting cancelled with ID: ${id}`);
    return successResponse(res, cancelled, HTTP_STATUS.OK);
  } catch (err) {
    logger.error("Error cancelling zoom meeting:", err);
    next(err);
  }
};

// Schedule Zoom Meeting from ScheduleZoom UI component
export const schedule = async (req, res, next) => {
  try {
    const normalized = normalizeScheduleZoomPayload(req.body);
    
    // Detect source from request if not provided
    if (!normalized.source) {
      const origin = req.headers.origin || req.headers.referer || "";
      if (origin.includes("aibitsoft.com")) {
        normalized.source = "abitsoft";
      } else if (origin.includes("aibitsol.com")) {
        normalized.source = "abitsol";
      } else {
        normalized.source = "abitsol"; // Default
      }
    }
    
    const parsed = scheduleZoomMeetingSchema.safeParse(normalized);
    
    if (!parsed.success) {
      // Format validation errors for better readability
      const formattedErrors = parsed.error.flatten();
      const errorMessages = Object.entries(formattedErrors.fieldErrors || {})
        .map(([field, errors]) => `${field}: ${Array.isArray(errors) ? errors.join(', ') : errors}`)
        .join('; ');
      
      logger.warn("Validation failed for schedule-zoom:", formattedErrors);
      
      return errorResponse(
        res,
        `Validation failed: ${errorMessages || 'Invalid input data'}`,
        HTTP_STATUS.BAD_REQUEST,
        formattedErrors
      );
    }

    const meeting = await createZoomMeetingFromSchedule(parsed.data);

    logger.info(`Zoom meeting scheduled: ${meeting.topic}`);

    return successResponse(
      res,
      {
        success: true,
        meeting,
        message: "Zoom meeting created successfully. All participants have been notified via email.",
      },
      HTTP_STATUS.CREATED
    );
  } catch (err) {
    logger.error("Error scheduling Zoom meeting:", err);
    
    // Return error in a format that's easy to handle on the frontend
    return errorResponse(
      res,
      err.message || "Failed to schedule Zoom meeting",
      err.response?.status || HTTP_STATUS.INTERNAL_SERVER_ERROR,
      err.response?.data || { error: err.message }
    );
  }
};

