import type { Database, EventAndTablo } from "@xtablo/shared-types";
import jsPDF from "jspdf";
import pluralizeLib from "pluralize";

/**
 * Re-export pluralize library for use throughout the app
 */
export const pluralize = pluralizeLib;

export const calculateTax = (amount: number, taxRate: number) => {
  return (amount * taxRate) / 100;
};

export const calculateTotal = (amount: number, tax: number) => {
  return amount + tax;
};

export const statusToText: Record<Devis["status"], string> = {
  draft: "Brouillon",
  sent: "Envoyé",
  accepted: "Accepté",
  rejected: "Rejeté",
  expired: "Expiré",
};

type Devis = Database["public"]["Tables"]["devis"]["Row"];

export const exportDevisToPdf = (devis: Devis) => {
  const doc = new jsPDF();

  // --- Basic PDF Content ---
  doc.setFontSize(22);
  doc.text(`Devis ${devis.number}`, 20, 20);

  doc.setFontSize(12);
  doc.text(`Client: ${devis.client_email}`, 20, 40);

  doc.text(`Date: ${new Date(devis.date).toLocaleDateString("fr-FR")}`, 140, 40);
  doc.text(`Date d'échéance: ${new Date(devis.due_date).toLocaleDateString("fr-FR")}`, 140, 48);

  // --- Amounts ---
  const startYAmounts = 70;
  doc.line(20, startYAmounts - 5, 190, startYAmounts - 5); // Separator line
  doc.text(`Sous-total HT: ${devis.subtotal.toFixed(2)} €`, 140, startYAmounts);
  doc.text(`TVA: ${devis.tax.toFixed(2)} €`, 140, startYAmounts + 8);
  doc.setFontSize(14);
  doc.setFont("helvetica", "bold");
  doc.text(`Total TTC: ${devis.total.toFixed(2)} €`, 140, startYAmounts + 18);
  doc.setFont("helvetica", "normal"); // Reset font
  doc.line(20, startYAmounts + 25, 190, startYAmounts + 25); // Separator line

  // --- Notes & Terms (if available) ---
  let currentY = startYAmounts + 40;
  if (devis.notes) {
    doc.setFontSize(12);
    doc.setFont("helvetica", "bold");
    doc.text("Notes:", 20, currentY);
    doc.setFont("helvetica", "normal");
    // Use splitTextToSize for wrapping long text
    const notesLines = doc.splitTextToSize(devis.notes, 170); // 170 is max width
    doc.text(notesLines, 20, currentY + 8);
    currentY += notesLines.length * 5 + 15; // Adjust Y position based on lines
  }

  if (devis.terms) {
    doc.setFontSize(12);
    doc.setFont("helvetica", "bold");
    doc.text("Conditions:", 20, currentY);
    doc.setFont("helvetica", "normal");
    const termsLines = doc.splitTextToSize(devis.terms, 170);
    doc.text(termsLines, 20, currentY + 8);
  }

  // --- Save the PDF ---
  doc.save(`devis_${devis.number}.pdf`);
};

// ICS Export functionality
export const generateICSFromEvents = (
  events: EventAndTablo[],
  calendarName: string = "Planning"
) => {
  const formatDate = (date: string, time: string) => {
    // Combine date (YYYY-MM-DD) and time (HH:MM:SS) into ISO format then convert to UTC
    const dateTime = new Date(`${date}T${time}`);
    return `${dateTime.toISOString().replace(/[-:]/g, "").split(".")[0]}Z`;
  };

  const escapeICSText = (text: string) => {
    return text
      .replace(/\\/g, "\\\\")
      .replace(/;/g, "\\;")
      .replace(/,/g, "\\,")
      .replace(/\n/g, "\\n")
      .replace(/\r/g, "");
  };

  const generateUID = (eventId: string) => {
    return `${eventId}@xtablo.com`;
  };

  let icsContent = [
    "BEGIN:VCALENDAR",
    "VERSION:2.0",
    "PRODID:-//XTablo//Planning Export//EN",
    `X-WR-CALNAME:${escapeICSText(calendarName)}`,
    "X-WR-TIMEZONE:Europe/Paris",
    "CALSCALE:GREGORIAN",
    "METHOD:PUBLISH",
  ].join("\r\n");

  events.forEach((event) => {
    if (!event.start_date || !event.start_time || !event.title) return;

    const startDateTime = formatDate(event.start_date, event.start_time);
    const endDateTime = event.end_time
      ? formatDate(event.start_date, event.end_time)
      : formatDate(event.start_date, event.start_time); // Default to start time if no end time

    const eventLines = [
      "",
      "BEGIN:VEVENT",
      `UID:${generateUID(event.event_id)}`,
      `DTSTART:${startDateTime}`,
      `DTEND:${endDateTime}`,
      `SUMMARY:${escapeICSText(event.title)}`,
      `DESCRIPTION:${escapeICSText(`Tablo: ${event.tablo_name}\n${event.description || ""}`)}`,
      event.tablo_name ? `CATEGORIES:${escapeICSText(event.tablo_name)}` : "",
      `CREATED:${new Date().toISOString().replace(/[-:]/g, "").split(".")[0]}Z`,
      `LAST-MODIFIED:${new Date().toISOString().replace(/[-:]/g, "").split(".")[0]}Z`,
      "STATUS:CONFIRMED",
      "TRANSP:OPAQUE",
      "END:VEVENT",
    ].filter((line) => line !== ""); // Remove empty lines

    icsContent += `\r\n${eventLines.join("\r\n")}`;
  });

  icsContent += "\r\n" + "END:VCALENDAR";
  return icsContent;
};

export const downloadICSFile = (icsContent: string, filename: string = "planning.ics") => {
  const blob = new Blob([icsContent], { type: "text/calendar;charset=utf-8" });
  const link = document.createElement("a");
  link.href = URL.createObjectURL(blob);
  link.download = filename;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  URL.revokeObjectURL(link.href);
};

// ICS Import functionality
export interface ParsedICSEvent {
  title: string;
  description?: string;
  start_date: string;
  start_time: string;
  end_time?: string;
}

export const parseICSFile = (icsContent: string): ParsedICSEvent[] => {
  const events: ParsedICSEvent[] = [];
  const lines = icsContent.split(/\r?\n/);

  let currentEvent: Partial<ParsedICSEvent> | null = null;

  const unescapeICSText = (text: string) => {
    return text
      .replace(/\\n/g, "\n")
      .replace(/\\,/g, ",")
      .replace(/\\;/g, ";")
      .replace(/\\\\/g, "\\");
  };

  const parseDateTime = (dateTimeStr: string) => {
    // Handle both YYYYMMDDTHHMMSSZ and YYYYMMDDTHHMMSS formats
    const cleanDate = dateTimeStr.replace(/[TZ]/g, "");

    if (cleanDate.length >= 8) {
      const year = cleanDate.substring(0, 4);
      const month = cleanDate.substring(4, 6);
      const day = cleanDate.substring(6, 8);
      const date = `${year}-${month}-${day}`;

      if (cleanDate.length >= 14) {
        const hour = cleanDate.substring(8, 10);
        const minute = cleanDate.substring(10, 12);
        const second = cleanDate.substring(12, 14) || "00";
        const time = `${hour}:${minute}:${second}`;
        return { date, time };
      } else {
        return { date, time: "00:00:00" };
      }
    }
    return null;
  };

  for (let i = 0; i < lines.length; i++) {
    let line = lines[i]?.trim() || "";

    // Handle line folding (lines starting with space or tab)
    while (i + 1 < lines.length && /^[ \t]/.test(lines[i + 1] || "")) {
      line += lines[i + 1]?.substring(1) || "";
      i++;
    }

    if (line === "BEGIN:VEVENT") {
      currentEvent = {};
    } else if (line === "END:VEVENT" && currentEvent) {
      if (currentEvent.title && currentEvent.start_date && currentEvent.start_time) {
        events.push(currentEvent as ParsedICSEvent);
      }
      currentEvent = null;
    } else if (currentEvent && line.includes(":")) {
      const colonIndex = line.indexOf(":");
      const property = line.substring(0, colonIndex);
      const value = line.substring(colonIndex + 1);

      // Handle properties that might have parameters (e.g., DTSTART;TZID=...)
      const [propName] = property.split(";");

      switch (propName) {
        case "SUMMARY":
          currentEvent.title = unescapeICSText(value);
          break;
        case "DESCRIPTION":
          currentEvent.description = unescapeICSText(value);
          break;
        case "DTSTART": {
          const startDateTime = parseDateTime(value);
          if (startDateTime) {
            currentEvent.start_date = startDateTime.date;
            currentEvent.start_time = startDateTime.time;
          }
          break;
        }
        case "DTEND": {
          const endDateTime = parseDateTime(value);
          if (endDateTime) {
            // Only use end time if it's on the same date
            const startDate = currentEvent.start_date;
            if (startDate === endDateTime.date) {
              currentEvent.end_time = endDateTime.time;
            }
          }
          break;
        }
      }
    }
  }

  return events;
};

export const getTextColorFromTabloColor = (tabloColor: string): string => {
  // Map of tablo background colors to their corresponding text colors
  const colorMap: Record<string, string> = {
    // Blue variants
    "bg-blue-100": "text-blue-800",
    "bg-blue-200": "text-blue-900",
    "bg-blue-300": "text-blue-900",
    "bg-blue-400": "text-white",
    "bg-blue-500": "text-white",
    "bg-blue-600": "text-white",
    "bg-blue-700": "text-white",
    "bg-blue-800": "text-white",
    "bg-blue-900": "text-white",

    // Green variants
    "bg-green-100": "text-green-800",
    "bg-green-200": "text-green-900",
    "bg-green-300": "text-green-900",
    "bg-green-400": "text-white",
    "bg-green-500": "text-white",
    "bg-green-600": "text-white",
    "bg-green-700": "text-white",
    "bg-green-800": "text-white",
    "bg-green-900": "text-white",

    // Red variants
    "bg-red-100": "text-red-800",
    "bg-red-200": "text-red-900",
    "bg-red-300": "text-red-900",
    "bg-red-400": "text-white",
    "bg-red-500": "text-white",
    "bg-red-600": "text-white",
    "bg-red-700": "text-white",
    "bg-red-800": "text-white",
    "bg-red-900": "text-white",

    // Yellow variants
    "bg-yellow-100": "text-yellow-800",
    "bg-yellow-200": "text-yellow-900",
    "bg-yellow-300": "text-yellow-900",
    "bg-yellow-400": "text-yellow-900",
    "bg-yellow-500": "text-white",
    "bg-yellow-600": "text-white",
    "bg-yellow-700": "text-white",
    "bg-yellow-800": "text-white",
    "bg-yellow-900": "text-white",

    // Purple variants
    "bg-purple-100": "text-purple-800",
    "bg-purple-200": "text-purple-900",
    "bg-purple-300": "text-purple-900",
    "bg-purple-400": "text-white",
    "bg-purple-500": "text-white",
    "bg-purple-600": "text-white",
    "bg-purple-700": "text-white",
    "bg-purple-800": "text-white",
    "bg-purple-900": "text-white",

    // Pink variants
    "bg-pink-100": "text-pink-800",
    "bg-pink-200": "text-pink-900",
    "bg-pink-300": "text-pink-900",
    "bg-pink-400": "text-white",
    "bg-pink-500": "text-white",
    "bg-pink-600": "text-white",
    "bg-pink-700": "text-white",
    "bg-pink-800": "text-white",
    "bg-pink-900": "text-white",

    // Indigo variants
    "bg-indigo-100": "text-indigo-800",
    "bg-indigo-200": "text-indigo-900",
    "bg-indigo-300": "text-indigo-900",
    "bg-indigo-400": "text-white",
    "bg-indigo-500": "text-white",
    "bg-indigo-600": "text-white",
    "bg-indigo-700": "text-white",
    "bg-indigo-800": "text-white",
    "bg-indigo-900": "text-white",

    // Gray variants
    "bg-gray-100": "text-gray-800",
    "bg-gray-200": "text-gray-900",
    "bg-gray-300": "text-gray-900",
    "bg-gray-400": "text-white",
    "bg-gray-500": "text-white",
    "bg-gray-600": "text-white",
    "bg-gray-700": "text-white",
    "bg-gray-800": "text-white",
    "bg-gray-900": "text-white",
  };

  return colorMap[tabloColor] || "text-gray-900";
};
