/**
 * Ethiopian Calendar Month Calculator
 * Maps Ethiopian months to Gregorian months and calculates available months based on date ranges
 */

// Ethiopian months mapping to Gregorian months
// Ethiopian calendar: Meskerem (1) - Pagume (13)
// Gregorian mapping: Sep (9) - Aug (8) of next year
// Amharic month names have multiple accepted spellings (e.g. ሚያዝያ vs ሚያዚያ,
// ነሐሴ vs ነሃሴ). Each entry lists every spelling we have seen from the backend
// so the parser does not silently fall back to month=1.
const ETHIOPIAN_MONTHS = [
  {
    ethMonth: 1,
    name: "Meskerem",
    amharicNames: ["መስከረም"],
    abbr: "MES",
    gregMonth: 9,
    gregMonthName: "September",
  },
  {
    ethMonth: 2,
    name: "Tekemt",
    amharicNames: ["ጥቅምት"],
    abbr: "TEK",
    gregMonth: 10,
    gregMonthName: "October",
  },
  {
    ethMonth: 3,
    name: "Hedar",
    amharicNames: ["ኅዳር", "ህዳር", "ሕዳር"],
    abbr: "HED",
    gregMonth: 11,
    gregMonthName: "November",
  },
  {
    ethMonth: 4,
    name: "Tahsas",
    amharicNames: ["ታኅሣሥ", "ታህሳስ", "ታህሳሥ"],
    abbr: "TAH",
    gregMonth: 12,
    gregMonthName: "December",
  },
  {
    ethMonth: 5,
    name: "Tir",
    amharicNames: ["ጥር"],
    abbr: "TIR",
    gregMonth: 1,
    gregMonthName: "January",
  },
  {
    ethMonth: 6,
    name: "Yekatit",
    amharicNames: ["የካቲት"],
    abbr: "YEK",
    gregMonth: 2,
    gregMonthName: "February",
  },
  {
    ethMonth: 7,
    name: "Megabit",
    amharicNames: ["መጋቢት"],
    abbr: "MEG",
    gregMonth: 3,
    gregMonthName: "March",
  },
  {
    ethMonth: 8,
    name: "Miazia",
    amharicNames: ["ሚያዝያ", "ሚያዚያ"],
    abbr: "MIA",
    gregMonth: 4,
    gregMonthName: "April",
  },
  {
    ethMonth: 9,
    name: "Genbot",
    amharicNames: ["ግንቦት"],
    abbr: "GEN",
    gregMonth: 5,
    gregMonthName: "May",
  },
  {
    ethMonth: 10,
    name: "Sene",
    amharicNames: ["ሰኔ"],
    abbr: "SEN",
    gregMonth: 6,
    gregMonthName: "June",
  },
  {
    ethMonth: 11,
    name: "Hamle",
    amharicNames: ["ሐምሌ", "ሃምሌ"],
    abbr: "HAM",
    gregMonth: 7,
    gregMonthName: "July",
  },
  {
    ethMonth: 12,
    name: "Nehase",
    amharicNames: ["ነሐሴ", "ነሃሴ"],
    abbr: "NEH",
    gregMonth: 8,
    gregMonthName: "August",
  },
  {
    ethMonth: 13,
    name: "Pagume",
    amharicNames: ["ጳጉሜ", "ጳጉሜን"],
    abbr: "PAG",
    gregMonth: 9,
    gregMonthName: "September (next year)",
  },
];

// Gregorian to Ethiopian month mapping (for reverse lookup)
const GREGORIAN_TO_ETHIOPIAN: { [key: number]: number } = {
  9: 1, // September -> Meskerem
  10: 2, // October -> Tekemt
  11: 3, // November -> Hedar
  12: 4, // December -> Tahsas
  1: 5, // January -> Tir
  2: 6, // February -> Yekatit
  3: 7, // March -> Megabit
  4: 8, // April -> Miazia
  5: 9, // May -> Genbot
  6: 10, // June -> Sene
  7: 11, // July -> Hamle
  8: 12, // August -> Nehase
};

// Gregorian month keys used in the API (Jul-Jun cycle)
const GREGORIAN_MONTH_KEYS = [
  "jul",
  "aug",
  "sep",
  "oct",
  "nov",
  "dec",
  "jan",
  "feb",
  "mar",
  "apr",
  "may",
  "jun",
];

export const monthsConfig: MonthConfig[] = [
  {
    key: "jul",
    name: "July",
    abbr: "JUL",
    index: 1,
    apiKey: "planned_jul",
    value: 11,
  },
  {
    key: "aug",
    name: "August",
    abbr: "AUG",
    index: 2,
    apiKey: "planned_aug",
    value: 12,
  },
  {
    key: "sep",
    name: "September",
    abbr: "SEP",
    index: 3,
    apiKey: "planned_sep",
    value: 1,
  },
  {
    key: "oct",
    name: "October",
    abbr: "OCT",
    index: 4,
    apiKey: "planned_oct",
    value: 2,
  },
  {
    key: "nov",
    name: "November",
    abbr: "NOV",
    index: 5,
    apiKey: "planned_nov",
    value: 3,
  },
  {
    key: "dec",
    name: "December",
    abbr: "DEC",
    index: 6,
    apiKey: "planned_dec",
    value: 4,
  },
  {
    key: "jan",
    name: "January",
    abbr: "JAN",
    index: 7,
    apiKey: "planned_jan",
    value: 5,
  },
  {
    key: "feb",
    name: "February",
    abbr: "FEB",
    index: 8,
    apiKey: "planned_feb",
    value: 6,
  },
  {
    key: "mar",
    name: "March",
    abbr: "MAR",
    index: 9,
    apiKey: "planned_mar",
    value: 7,
  },
  {
    key: "apr",
    name: "April",
    abbr: "APR",
    index: 10,
    apiKey: "planned_apr",
    value: 8,
  },
  {
    key: "may",
    name: "May",
    abbr: "MAY",
    index: 11,
    apiKey: "planned_may",
    value: 9,
  },
  {
    key: "jun",
    name: "June",
    abbr: "JUN",
    index: 12,
    apiKey: "planned_jun",
    value: 10,
  },
];

interface MonthConfig {
  key: string;
  name: string;
  abbr: string;
  index: number;
  apiKey: string;
  value: number;
  ethMonth?: number;
  ethMonthName?: string;
}

/**
 * Parse Ethiopian date string. Supports both:
 *   "ሚያዚያ 01/2018 - 09:00 ሌሊት"   (slash between day and year)
 *   "ታኅሣሥ 06: 2018 - 12:51 ማታ"   (legacy: colon between day and year)
 */
export const parseEthiopianDateString = (
  dateStr: string
): { year: number; month: number; day: number } | null => {
  try {
    const trimmed = dateStr.trim();

    // Match "<MonthName> <DD><sep><YYYY>" where <sep> is "/" or ":"
    const match = trimmed.match(/^(\S+)\s+(\d+)\s*[\/:]\s*(\d+)/);
    if (!match) return null;

    const [, monthName, dayStr, yearStr] = match;
    const monthConfig = ETHIOPIAN_MONTHS.find(
      (m) => m.name === monthName || m.amharicNames.includes(monthName)
    );

    if (!monthConfig) {
      console.warn(
        `Unknown Ethiopian month name "${monthName}" in "${dateStr}"`
      );
    }

    return {
      year: parseInt(yearStr),
      month: monthConfig?.ethMonth || 1,
      day: parseInt(dayStr),
    };
  } catch (error) {
    console.error("Error parsing Ethiopian date:", error);
    return null;
  }
};

/**
 * Calculate available months based on start and end dates
 * Returns filtered monthsConfig with only available months
 */
export const calculateAvailableMonths = (
  startDateStr: string,
  endDateStr: string,
  allMonthsConfig: MonthConfig[]
): MonthConfig[] => {
  try {
    const startDate = parseEthiopianDateString(startDateStr);
    const endDate = parseEthiopianDateString(endDateStr);

    if (!startDate || !endDate) {
      console.warn("Could not parse dates, returning all months");
      return allMonthsConfig;
    }

    console.log("Start Date (Ethiopian):", startDate);
    console.log("End Date (Ethiopian):", endDate);

    // If same year, filter months between start and end
    if (startDate.year === endDate.year) {
      return allMonthsConfig.filter((month) => {
        const monthNum = month.value; // value represents Ethiopian month number
        return monthNum >= startDate.month && monthNum <= endDate.month;
      });
    }

    // If spanning multiple years, include all months from start to end
    // This handles cases where the plan spans across Ethiopian year boundary
    return allMonthsConfig.filter((month) => {
      const monthNum = month.value;

      // Include months from start month onwards in start year
      if (monthNum >= startDate.month) {
        return true;
      }

      // Include months up to end month in end year
      if (monthNum <= endDate.month) {
        return true;
      }

      return false;
    });
  } catch (error) {
    console.error("Error calculating available months:", error);
    return allMonthsConfig;
  }
};

/**
 * Filter months config to only include months that have employee plans
 * @param allMonthsConfig - All available months
 * @param employeePlanMonths - Array of month numbers from employee plans
 * @returns Filtered months config
 */
export const filterMonthsByEmployeePlans = (
  allMonthsConfig: MonthConfig[],
  employeePlanMonths: number[]
): MonthConfig[] => {
  console.log("filterMonthsByEmployeePlans called with:", {
    allMonthsConfigLength: allMonthsConfig.length,
    employeePlanMonths,
    monthValues: allMonthsConfig.map((m) => ({ key: m.key, value: m.value })),
  });

  if (!employeePlanMonths || employeePlanMonths.length === 0) {
    console.log("No employee plan months provided, returning all months");
    return allMonthsConfig;
  }

  const filtered = allMonthsConfig.filter((month) => {
    const matches = employeePlanMonths.includes(month.value);
    console.log(
      `Month ${month.key} (value: ${month.value}) matches: ${matches}`
    );
    return matches;
  });

  console.log(
    "Filtered result:",
    filtered.map((m) => ({ key: m.key, value: m.value }))
  );
  return filtered;
};

/**
 * Get month config with Ethiopian month information
 */
export const getEnhancedMonthsConfig = (
  baseConfig: MonthConfig[]
): MonthConfig[] => {
  return baseConfig.map((month) => {
    const ethMonth = ETHIOPIAN_MONTHS.find(
      (em) =>
        em.gregMonth === parseInt(month.name.substring(0, 2)) ||
        em.abbr === month.abbr
    );
    return {
      ...month,
      ethMonth: ethMonth?.ethMonth,
      ethMonthName: ethMonth?.name,
    };
  });
};

/**
 * Convert Gregorian month number to Ethiopian month number
 */
export const gregMonthToEthMonth = (gregMonth: number): number => {
  return GREGORIAN_TO_ETHIOPIAN[gregMonth] || 1;
};

/**
 * Get month name in both Gregorian and Ethiopian
 */
export const getMonthDisplayName = (monthKey: string): string => {
  const monthIndex = GREGORIAN_MONTH_KEYS.indexOf(monthKey);
  if (monthIndex === -1) return monthKey;

  const ethMonth = ETHIOPIAN_MONTHS[monthIndex];
  return `${monthKey.toUpperCase()} (${ethMonth.name})`;
};
