const BASE_URL = process.env.REACT_APP_API_URL || "http://localhost:8080/api";
const XLSX = require("xlsx-js-style");

// Helper function for handling fetch requests
const fetchData = async (url, options) => {
  try {
    const response = await fetch(url, options);

    // Check if response is OK (status 200-299)
    if (!response.ok) {
      let errorDetails = {};
      try {
        errorDetails = await response.json(); // Attempt to parse error response
      } catch (err) {
        console.warn("Failed to parse error details:", err);
      }
      throw new Error(
        `Error: ${response.statusText} (${response.status}) - ${
          errorDetails.message || "No details available"
        }`
      );
    }

    // Return JSON response if successful
    return await response.json();
  } catch (error) {
    console.error(`Request failed for ${url}:`, error.message);
    throw error; // Re-throw for the caller to handle
  }
};

// Fetch courses with optional filters
export const fetchCourses = async (filterData = {}) => {
  try {
    const queryString = new URLSearchParams(filterData).toString();
    const url = `${BASE_URL}/courses?${queryString}`;
    return fetchData(url, {
      method: "GET",
      headers: {
        "Content-Type": "application/json",
      },
    });
  } catch (error) {
    console.error("Error fetching courses:", error.message);
    throw error;
  }
};

// Fetch list of faculties
export const fetchFaculties = async () => {
  try {
    const url = `${BASE_URL}/faculty`;
    return fetchData(url, {
      method: "GET",
      headers: {
        "Content-Type": "application/json",
      },
    });
  } catch (error) {
    console.error("Error fetching faculties:", error.message);
    throw error;
  }
};

// Fetch available options for form dropdowns
export const fetchOptions = async () => {
  try {
    const url = `${BASE_URL}/options`;
    return fetchData(url, {
      method: "GET",
      headers: {
        "Content-Type": "application/json",
      },
    });
  } catch (error) {
    console.error("Error fetching options:", error.message);
    throw error;
  }
};

export const fetchAppointments = async (academicYear) => {
  try {
    const response = await fetch(`${BASE_URL}/appointments?academicYear=${academicYear}`);
    if (!response.ok) {
      throw new Error("Failed to fetch appointments");
    }
    return await response.json();
  } catch (error) {
    console.error(error);
    return [];
  }
};

// Save multiple appointments to MongoDB
export const saveAppointment = async (appointmentsData) => {
  console.log("Saving appointments with payload:", appointmentsData);

  // Validate input format
  if (!Array.isArray(appointmentsData) || appointmentsData.length === 0) {
    const errorMessage =
      "Invalid or missing appointment data: expected a non-empty array";
    console.error(errorMessage);
    throw new Error(errorMessage);
  }

  // Validate each appointment's structure
  const invalidEntries = appointmentsData.filter(
    (appointment) =>
      !appointment.facultyId || !appointment.courseId || !Array.isArray(appointment.tasks)
  );

  if (invalidEntries.length > 0) {
    const errorMessage = `Invalid appointments detected: ${JSON.stringify(
      invalidEntries
    )}`;
    console.error(errorMessage);
    throw new Error(errorMessage);
  }

  try {
    const url = `${BASE_URL}/appointments`;
    const response = await fetchData(url, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ appointments: appointmentsData }), // Send appointments as an array
    });

    console.log("Appointments saved successfully:", response);
    return response;
  } catch (error) {
    console.error("Error saving appointments:", error.message);
    throw error;
  }
};

// Update course status
export const updateCourseStatus = async (courseId) => {
  if (!courseId) {
    throw new Error("Course ID is required to update the status");
  }

  const url = `${BASE_URL}/courses/${courseId}`;
  return fetchData(url, {
    method: "PATCH",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ status: "submitted" }), // Update status to "Submitted"
  });
};

export const sendEmail = async (formData, type) => {
  try {
    const url = `${BASE_URL}/send-email/${type}`;
    const response = await fetch(url, {
      method: "POST",
      body: formData, // Directly pass FormData
    });

    if (!response.ok) {
      let errorDetails = {};
      try {
        errorDetails = await response.json();
      } catch (err) {
        console.warn("Failed to parse error details:", err);
      }
      throw new Error(
        `Error: ${response.statusText} (${response.status}) - ${
          errorDetails.message || "No details available"
        }`
      );
    }

    return await response.json();
  } catch (error) {
    console.error( error.message);
    throw error;
  }
};

export   const createExcelBook = (teacherData, teacher) => {
  const workbook = XLSX.utils.book_new();

  // Extract academicYear and examPeriod from the first entry in the teacherData array
  const { academicYear, examPeriod } = teacherData[0] || {};

  // Define header information
  const headerInfo = [
    ["Somaiya Vidyavihar University"],
    ["K. J. SOMAIYA COLLEGE OF ENGINEERING"],
    [`Examination: ${examPeriod} ${academicYear}`],
    [
      "Appointment of Internal Examiners for Paper Setting / OR/PR/Assessment/Reassessment",
    ],
    ["Class: B Tech/M Tech/Honour/Minor"],
    ["Department - Computer Engineering"],
    [],
  ];

  const tableHeaders = [
    [
      "Sr No",
      "Semester",
      "Program",
      "Course Code",
      "Course Name",
      "Exam Type",
      "Year",
      "Marks",
      "Name",
      "Affiliation/College",
      "Highest Qualification",
      "Career Experience",
      "Oral/Practical",
      "Assessment",
      "Reassessment",
      "Paper Setting",
      "Moderation",
      "PwD Paper Setting",
    ],
  ];

  const dataRows = teacherData.map((row, index) => [
    index + 1,
    row.semester,
    row.program,
    row.courseCode,
    row.courseName,
    row.examType,
    Math.ceil(row.semester/2),
    row.marks,
    row.Name,
    row.affiliation,
    row.qualification,
    row.experience,
    row.oralPractical,
    row.assessment,
    row.reassessment,
    row.paperSetting,
    row.moderation,
    row.pwdPaperSetting,
  ]);

  const sheetData = [...headerInfo, ...tableHeaders, ...dataRows];
  const worksheet = XLSX.utils.aoa_to_sheet(sheetData);

  // Add merged cells
  worksheet["!merges"] = [
    { s: { r: 0, c: 0 }, e: { r: 0, c: 18 } },
    { s: { r: 1, c: 0 }, e: { r: 1, c: 18 } },
    { s: { r: 2, c: 0 }, e: { r: 2, c: 18 } },
    { s: { r: 3, c: 0 }, e: { r: 3, c: 18 } },
    { s: { r: 4, c: 0 }, e: { r: 4, c: 18 } },
  ];

  // Define styles
  const boldStyle = {
    font: { bold: true, name: "Times New Roman", sz: 14 },
    alignment: { horizontal: "center", vertical: "center" },
  };

  const redStyle = {
    font: {
      bold: true,
      color: { rgb: "FF0000" },
      name: "Times New Roman",
      sz: 14,
    },
    alignment: { horizontal: "center", vertical: "center" },
  };

  const normalStyle = {
    font: { name: "Times New Roman", sz: 12 },
  };

  // Apply styles to headers
  const headerRanges = [
    { row: 0, style: boldStyle },
    { row: 1, style: boldStyle },
    { row: 2, style: boldStyle },
    { row: 3, style: boldStyle },
    { row: 4, style: redStyle },
  ];

  headerRanges.forEach(({ row, style }) => {
    for (let col = 0; col <= 18; col++) {
      const cellAddress = XLSX.utils.encode_cell({ r: row, c: col });
      if (!worksheet[cellAddress]) continue; // Skip empty cells
      worksheet[cellAddress].s = style;
    }
  });

  // Set column widths for better readability
  worksheet["!cols"] = [
    { wch: 10 }, // Sr No
    { wch: 12 }, // Semester
    { wch: 15 }, // Course Code
    { wch: 25 }, // Course Name
    { wch: 15 }, // Exam Type
    { wch: 10 }, // Year
    { wch: 10 }, // Marks
    { wch: 15 }, // Surname
    { wch: 15 }, // First Name
    { wch: 15 }, // Middle Name
    { wch: 20 }, // Affiliation
    { wch: 20 }, // Qualification
    { wch: 15 }, // Career Experience
    { wch: 15 }, // Oral/Practical
    { wch: 15 }, // Assessment
    { wch: 15 }, // Reassessment
    { wch: 15 }, // Paper Setting
    { wch: 15 }, // Moderation
    { wch: 15 }, // PwD Paper Setting
  ];

  // Apply normal font style to all cells
  Object.keys(worksheet).forEach((key) => {
    if (worksheet[key] && key[0] !== "!") {
      worksheet[key].s = worksheet[key].s || normalStyle;
    }
  });

  // Add worksheet to workbook and save file
  XLSX.utils.book_append_sheet(workbook, worksheet, teacher);
  return workbook;
}