/**
 * Phone ↔ LID Mapping
 * 
 * WhatsApp NOWEB sometimes uses LID (Linked Device ID) format instead of phone numbers.
 * This module maps between the two so we can find leads from LID-format messages.
 * 
 * When we send to "201066544750@c.us" and get a reply from "274156486697100@lid",
 * we store the mapping so future messages from that LID resolve to the correct phone.
 */

import { prisma } from "./db";

// Bidirectional in-memory map
const lidToPhone = new Map<string, string>();
const phoneToLid = new Map<string, string>();

/**
 * Register a known LID ↔ phone mapping
 */
export function registerMapping(lid: string, phone: string) {
  const cleanLid = lid.replace("@lid", "").replace("@c.us", "");
  const cleanPhone = phone.replace(/[\s\-\+@a-z]/gi, "");
  lidToPhone.set(cleanLid, cleanPhone);
  phoneToLid.set(cleanPhone, cleanLid);
}

/**
 * Resolve any phone/LID to a clean phone number.
 * Returns the original (cleaned) if no mapping exists.
 */
export function resolveToPhone(input: string): string {
  const clean = input.replace("@lid", "").replace("@c.us", "").replace(/[\s\-\+]/g, "");
  return lidToPhone.get(clean) || clean;
}

/**
 * Build initial mappings from message history.
 * Called on startup to populate the map from existing conversations.
 */
export async function buildMappingsFromHistory(clinicId: string) {
  // Find all unique LID phones in incoming messages
  const lidMessages = await prisma.messageLog.findMany({
    where: {
      clinicId,
      direction: "incoming",
      phone: { contains: "@lid" },
    },
    select: { phone: true, createdAt: true },
    distinct: ["phone"],
  });

  for (const msg of lidMessages) {
    const lid = msg.phone.replace("@lid", "");
    
    // Find the most recent outgoing message BEFORE this LID first appeared
    const firstLidMsg = await prisma.messageLog.findFirst({
      where: { clinicId, phone: msg.phone, direction: "incoming" },
      orderBy: { createdAt: "asc" },
    });

    if (!firstLidMsg) continue;

    // Find outgoing messages to real phones sent shortly before
    const recentOutgoing = await prisma.messageLog.findFirst({
      where: {
        clinicId,
        direction: "outgoing",
        phone: { not: { contains: "@" } }, // Real phone numbers only
        createdAt: { lte: firstLidMsg.createdAt },
      },
      orderBy: { createdAt: "desc" },
    });

    if (recentOutgoing) {
      registerMapping(lid, recentOutgoing.phone);
      console.log(`📱 Mapped LID ${lid} → ${recentOutgoing.phone}`);
    }
  }
}

/**
 * Try to auto-detect mapping when a new LID message arrives.
 * Looks at who we recently sent messages to.
 */
export async function autoDetectMapping(
  clinicId: string,
  lidPhone: string
): Promise<string | null> {
  const clean = lidPhone.replace("@lid", "").replace("@c.us", "");
  
  // Already known?
  const existing = lidToPhone.get(clean);
  if (existing) return existing;

  // Find the most recent outgoing message to a real phone number
  // (the person we just messaged is most likely the one replying)
  const recentOutgoing = await prisma.messageLog.findFirst({
    where: {
      clinicId,
      direction: "outgoing",
      phone: { not: { contains: "@" } },
    },
    orderBy: { createdAt: "desc" },
  });

  if (recentOutgoing) {
    // Verify this phone belongs to a lead
    const phoneSuffix = recentOutgoing.phone.slice(-9);
    const lead = await prisma.lead.findFirst({
      where: { clinicId, phone: { contains: phoneSuffix } },
    });

    if (lead) {
      const cleanPhone = lead.phone.replace(/[\s\-\+]/g, "");
      registerMapping(clean, cleanPhone);
      console.log(`📱 Auto-mapped LID ${clean} → ${cleanPhone} (lead: ${lead.name})`);
      return cleanPhone;
    }
  }

  return null;
}
