export type ServicePaymentMode = "global" | "specific";

export interface ServicePaymentMeta {
  paymentMode?: ServicePaymentMode;
  serviceId?: number;
  serviceName?: string;
  proofUrls?: string[];
  uploader?: string;
}

const META_PREFIX = "[[MYRISTICA_META:";
const META_SUFFIX = "]]";

function normalizeUrls(urls: unknown): string[] {
  if (!Array.isArray(urls)) return [];

  return urls
    .filter((url): url is string => typeof url === "string" && /^https?:\/\//.test(url.trim()))
    .map((url) => url.trim());
}

function sanitizeMeta(meta: ServicePaymentMeta): ServicePaymentMeta {
  return {
    paymentMode: meta.paymentMode,
    serviceId: typeof meta.serviceId === "number" ? meta.serviceId : undefined,
    serviceName: typeof meta.serviceName === "string" ? meta.serviceName : undefined,
    proofUrls: normalizeUrls(meta.proofUrls),
    uploader: typeof meta.uploader === "string" ? meta.uploader : undefined,
  };
}

function hasMeaningfulMeta(meta: ServicePaymentMeta): boolean {
  return Boolean(
    meta.paymentMode ||
    meta.serviceId ||
    meta.serviceName ||
    meta.proofUrls?.length ||
    meta.uploader
  );
}

function cleanLegacyProofText(text: string): string {
  return text
    .replace(/\s*\|\s*comprobante[s]?:\s*https?:\/\/\S+/gi, "")
    .replace(/\s*-?\s*subido por\s+[^|]+?\s+via WhatsApp bot/gi, "")
    .replace(/https?:\/\/\S+/g, "")
    .replace(/[|\-:;,\s]+$/g, "")
    .replace(/\s{2,}/g, " ")
    .trim();
}

function extractLegacyUploader(text: string): string | undefined {
  const match = text.match(/subido por\s+([^|]+?)\s+via WhatsApp bot/i);
  if (!match?.[1]) return undefined;
  return `${match[1].trim()} via WhatsApp`;
}

export function buildServicePaymentNotes(visibleText: string, meta: ServicePaymentMeta): string {
  const cleanedText = visibleText.trim();
  const sanitized = sanitizeMeta(meta);

  if (!hasMeaningfulMeta(sanitized)) return cleanedText;

  return `${META_PREFIX}${JSON.stringify(sanitized)}${META_SUFFIX}${cleanedText ? ` ${cleanedText}` : ""}`;
}

export function parseServicePaymentNotes(rawNotes: string | null | undefined): {
  displayText: string;
  meta: ServicePaymentMeta;
} {
  if (!rawNotes) {
    return {
      displayText: "",
      meta: {},
    };
  }

  let remaining = rawNotes.trim();
  let meta: ServicePaymentMeta = {};

  const start = remaining.indexOf(META_PREFIX);
  if (start !== -1) {
    const end = remaining.indexOf(META_SUFFIX, start);
    if (end !== -1) {
      const payload = remaining.slice(start + META_PREFIX.length, end);
      try {
        meta = sanitizeMeta(JSON.parse(payload) as ServicePaymentMeta);
      } catch {
        meta = {};
      }

      remaining = `${remaining.slice(0, start)} ${remaining.slice(end + META_SUFFIX.length)}`.trim();
    }
  }

  const legacyUrls = Array.from(remaining.matchAll(/https?:\/\/\S+/g)).map((match) => match[0].trim());
  if (!meta.proofUrls?.length && legacyUrls.length) {
    meta = { ...meta, proofUrls: legacyUrls };
  }

  const legacyUploader = extractLegacyUploader(remaining);
  if (!meta.uploader && legacyUploader) {
    meta = { ...meta, uploader: legacyUploader };
  }

  return {
    displayText: cleanLegacyProofText(remaining),
    meta,
  };
}
