import { DEFAULT_LANGUAGE, type AppLanguage } from "@/lib/i18n/registry";
import { translateCommon } from "@/lib/i18n/translate";

function normalizeJalaliPrefix(raw: string): string | null {
  const match = raw.match(/^(\d{4})-(\d{1,2})-(\d{1,2})/);
  if (!match) return null;
  return `${match[1]}-${Number(match[2])}-${Number(match[3])}`;
}

function getTodayJalaliPrefix(): string | null {
  try {
    const parts = new Intl.DateTimeFormat("en-u-ca-persian", {
      year: "numeric",
      month: "numeric",
      day: "numeric",
    }).formatToParts(new Date());

    const year = parts.find((p) => p.type === "year")?.value;
    const month = parts.find((p) => p.type === "month")?.value;
    const day = parts.find((p) => p.type === "day")?.value;
    if (!year || !month || !day) return null;
    return `${year}-${Number(month)}-${Number(day)}`;
  } catch {
    return null;
  }
}

function getYesterdayJalaliPrefix(): string | null {
  const yesterday = new Date();
  yesterday.setDate(yesterday.getDate() - 1);
  try {
    const parts = new Intl.DateTimeFormat("en-u-ca-persian", {
      year: "numeric",
      month: "numeric",
      day: "numeric",
    }).formatToParts(yesterday);

    const year = parts.find((p) => p.type === "year")?.value;
    const month = parts.find((p) => p.type === "month")?.value;
    const day = parts.find((p) => p.type === "day")?.value;
    if (!year || !month || !day) return null;
    return `${year}-${Number(month)}-${Number(day)}`;
  } catch {
    return null;
  }
}

/** Parse message timestamp (ISO, Jalali, or datetime string) for grouping */
export function parseMessageDate(createdAt?: string | null): Date | null {
  if (!createdAt) return null;
  const raw = String(createdAt).trim();

  const jalaliPrefix = normalizeJalaliPrefix(raw);
  if (jalaliPrefix) {
    const [y, m, d] = jalaliPrefix.split("-").map(Number);
    return new Date(y, m - 1, d);
  }

  const parsed = new Date(raw);
  if (!Number.isNaN(parsed.getTime())) return parsed;
  return null;
}

function isSameDay(a: Date, b: Date): boolean {
  return a.toDateString() === b.toDateString();
}

function formatLocalizedDate(
  date: Date,
  withYear: boolean,
  lang: AppLanguage
): string {
  const locale = lang === "fa" ? "fa-IR" : "en-US";
  try {
    if (withYear) {
      return date.toLocaleDateString(locale, {
        year: "numeric",
        month: "long",
        day: "numeric",
      });
    }
    return date.toLocaleDateString(locale, {
      month: "long",
      day: "numeric",
    });
  } catch {
    return date.toDateString();
  }
}

/** Telegram-style date label: today, yesterday, or calendar date */
export function formatChatDateLabel(
  createdAt?: string | null,
  lang: AppLanguage = DEFAULT_LANGUAGE
): string {
  const raw = createdAt ? String(createdAt).trim() : "";
  const jalaliPrefix = normalizeJalaliPrefix(raw);

  if (jalaliPrefix) {
    const today = getTodayJalaliPrefix();
    const yesterday = getYesterdayJalaliPrefix();
    if (today && jalaliPrefix === today) {
      return translateCommon(lang, "chats.today");
    }
    if (yesterday && jalaliPrefix === yesterday) {
      return translateCommon(lang, "chats.yesterday");
    }

    const [y, m, d] = jalaliPrefix.split("-").map(Number);
    const date = new Date(y, m - 1, d);
    if (!Number.isNaN(date.getTime())) {
      return formatLocalizedDate(date, y !== new Date().getFullYear(), lang);
    }
    return jalaliPrefix.replace(/-/g, "/");
  }

  const d = parseMessageDate(createdAt) ?? new Date();
  const today = new Date();
  const yesterday = new Date();
  yesterday.setDate(today.getDate() - 1);

  if (isSameDay(d, today)) return translateCommon(lang, "chats.today");
  if (isSameDay(d, yesterday)) return translateCommon(lang, "chats.yesterday");

  if (d.getFullYear() === today.getFullYear()) {
    return formatLocalizedDate(d, false, lang);
  }

  return formatLocalizedDate(d, true, lang);
}

/** Bubble time: hours, minutes, seconds only (no date) */
export function formatBubbleTime(
  createdAt?: string | null,
  lang: AppLanguage = DEFAULT_LANGUAGE
): string {
  if (!createdAt) {
    return "";
  }

  const raw = String(createdAt).trim();
  const locale = lang === "fa" ? "fa-IR" : "en-US";

  // ISO datetime — always prefer real clock time
  if (raw.includes("T")) {
    const d = new Date(raw);
    if (!Number.isNaN(d.getTime())) {
      try {
        return d.toLocaleTimeString(locale, {
          hour: "2-digit",
          minute: "2-digit",
          second: "2-digit",
        });
      } catch {
        return raw;
      }
    }
  }

  const timePart = raw.includes(" ")
    ? raw.split(" ").pop()
    : raw.length <= 8 && raw.includes(":")
      ? raw
      : null;

  if (timePart && /^\d{1,2}:\d{2}(:\d{2})?$/.test(timePart)) {
    const parts = timePart.split(":");
    if (parts.length === 2) return `${parts[0]}:${parts[1]}:00`;
    return timePart;
  }

  const d = parseMessageDate(raw) ?? new Date(raw);
  if (!Number.isNaN(d.getTime())) {
    try {
      return d.toLocaleTimeString(locale, {
        hour: "2-digit",
        minute: "2-digit",
        second: "2-digit",
      });
    } catch {
      return raw;
    }
  }

  return raw;
}
