import { sendText, sendButtons, sendPresence } from "../evolution";
import { getSession, setSession, clearSession, type BotContext, type BotState } from "../sessions";
import { getActiveServices } from "../tools";
import { executeTool } from "../tools";

function normalizeReply(text: string): string {
  return text.trim().toLowerCase();
}

function numberFromReply(text: string): number | null {
  const match = text.match(/^\(?\s*(\d+)\s*[.)]?$/);
  if (!match) return null;

  const value = parseInt(match[1], 10);
  return Number.isFinite(value) ? value : null;
}

function uploaderLabel(senderName: string): string {
  return `${senderName} via WhatsApp`;
}

function globalServiceSummary(amount: number | undefined, date: string | undefined): string {
  return `Registrar pago global de servicios\n💰 $${amount?.toLocaleString("es-AR") ?? "?"}\n📅 ${date ?? "?"}`;
}

function specificServiceSummary(serviceName: string, amount: number | undefined, date: string | undefined): string {
  return `Registrar pago especifico de ${serviceName}\n💰 $${amount?.toLocaleString("es-AR") ?? "?"}\n📅 ${date ?? "?"}`;
}

async function mapTextReplyToButtonId(
  state: BotState,
  context: BotContext,
  rawText: string
): Promise<string | null> {
  const text = normalizeReply(rawText);
  const number = numberFromReply(text);

  if (state === "awaiting_payment_type") {
    if (number === 1 || ["si", "sí", "confirmar", "registrar"].includes(text)) return "confirm_yes";
    if (number === 2 || ["no", "ignorar", "cancelar"].includes(text)) return "confirm_no";
    return null;
  }

  if (state === "awaiting_service_select") {
    if (context.selectedPaymentType === "servicio") {
      if (["cancelar", "cancel", "salir"].includes(text)) return "pay_cancel";

      const activeServices = await getActiveServices();
      const options = activeServices.slice(0, 3).map((service) => `svc_${service.id}`);
      if (activeServices.length > 3) options.push("svc_otro");

      if (number !== null && number >= 1 && number <= options.length) {
        return options[number - 1];
      }

      if (text === "otro") return "svc_otro";
      return null;
    }

    if (number === 1 || text === "alquiler") return "pay_alquiler";
    if (number === 2 || ["servicio", "servicios"].includes(text)) return "pay_servicio";
    if (number === 3 || ["cancelar", "cancel", "salir"].includes(text)) return "pay_cancel";
    return null;
  }

  if (state === "awaiting_service_mode") {
    if (number === 1 || ["global", "general", "todos"].includes(text)) return "service_mode_global";
    if (number === 2 || ["especifico", "específico", "servicio"].includes(text)) return "service_mode_specific";
    if (number === 3 || ["cancelar", "cancel", "salir"].includes(text)) return "pay_cancel";
    return null;
  }

  if (state === "awaiting_specific_service_select") {
    if (["cancelar", "cancel", "salir"].includes(text)) return "pay_cancel";

    const activeServices = await getActiveServices();
    const options = activeServices.slice(0, 3).map((service) => `svc_${service.id}`);
    if (activeServices.length > 3) options.push("svc_otro");

    if (number !== null && number >= 1 && number <= options.length) {
      return options[number - 1];
    }

    if (text === "otro") return "svc_otro";
    return null;
  }

  if (state === "awaiting_confirm") {
    if (number === 1 || ["si", "sí", "confirmar", "ok", "dale", "listo", "yes", "registralo", "registrar", "hacelo", "metele", "confirmo"].includes(text)) return "final_confirm";
    if (number === 2 || ["no", "cancelar", "cancel", "salir"].includes(text)) return "final_cancel";
    return null;
  }

  return null;
}

export async function handleInteractiveTextReply(
  groupJid: string,
  senderPhone: string,
  senderName: string,
  text: string,
  silent = false
): Promise<"handled" | "unrecognized" | "idle"> {
  const { state, context } = await getSession(senderPhone);
  if (state === "idle") return "idle";

  const buttonId = await mapTextReplyToButtonId(state, context, text);
  if (!buttonId) {
    if (!silent) {
      await sendText(groupJid, "No entendi esa opcion. Responde con el numero exacto o escribi BOT ayuda.");
    }
    return "unrecognized";
  }

  await handleButtonReply(groupJid, senderPhone, senderName, buttonId);
  return "handled";
}

export async function handleButtonReply(
  groupJid: string,
  senderPhone: string,
  senderName: string,
  buttonId: string
) {
  let presenceInterval: ReturnType<typeof setInterval> | null = null;
  try {
  await sendPresence(groupJid, "composing");
  presenceInterval = setInterval(() => {
    void sendPresence(groupJid, "composing");
  }, 4000);

  const { state, context } = await getSession(senderPhone);

  // ── awaiting_payment_type: user said yes/no to registering ──
  if (state === "awaiting_payment_type") {
    if (buttonId === "confirm_no") {
      await clearSession(senderPhone);
      await sendText(groupJid, "Ok, comprobante descartado.");
      return;
    }

    if (buttonId === "confirm_yes") {
      await setSession(senderPhone, "awaiting_service_select", context);
      await sendButtons(
        groupJid,
        "¿A qué corresponde este pago?",
        `Monto: $${context.ocrData?.amount?.toLocaleString("es-AR") ?? "?"}`,
        [
          { id: "pay_alquiler", text: "🏠 Alquiler" },
          { id: "pay_servicio", text: "⚡ Servicios" },
          { id: "pay_cancel", text: "✖ Cancelar" },
        ]
      );
      return;
    }
  }

  // ── awaiting_service_select: alquiler vs servicio ──
  if (state === "awaiting_service_select") {
    if (buttonId === "pay_cancel") {
      await clearSession(senderPhone);
      await sendText(groupJid, "Operación cancelada.");
      return;
    }

    if (buttonId === "pay_alquiler") {
      const ocr = context.ocrData;
      const periodo = ocr?.date
        ? ocr.date.slice(0, 7)
        : new Date().toISOString().slice(0, 7);

      await setSession(senderPhone, "awaiting_confirm", {
        ...context,
        selectedPaymentType: "alquiler",
      });

      await sendButtons(
        groupJid,
        `Registrar pago de alquiler\n💰 $${ocr?.amount?.toLocaleString("es-AR") ?? "?"}\n📅 ${ocr?.date ?? "?"}\n📆 Período: ${periodo}`,
        "¿Confirmás?",
        [
          { id: "final_confirm", text: "✅ Confirmar" },
          { id: "final_cancel", text: "❌ Cancelar" },
        ]
      );
      return;
    }

    if (buttonId === "pay_servicio") {
      await setSession(senderPhone, "awaiting_service_mode", {
        ...context,
        selectedPaymentType: "servicio",
      });

      await sendButtons(
        groupJid,
        "¿El pago de servicios es global o especifico?",
        `Monto: $${context.ocrData?.amount?.toLocaleString("es-AR") ?? "?"}`,
        [
          { id: "service_mode_global", text: "Global" },
          { id: "service_mode_specific", text: "Especifico" },
          { id: "pay_cancel", text: "Cancelar" },
        ]
      );
      return;
    }
  }

  if (state === "awaiting_service_mode") {
    if (buttonId === "pay_cancel") {
      await clearSession(senderPhone);
      await sendText(groupJid, "Operación cancelada.");
      return;
    }

    if (buttonId === "service_mode_global") {
      const ocr = context.ocrData;

      await setSession(senderPhone, "awaiting_confirm", {
        ...context,
        selectedPaymentType: "servicio",
        selectedServicePaymentMode: "global",
        selectedServiceId: undefined,
        selectedServiceName: undefined,
      });

      await sendButtons(
        groupJid,
        globalServiceSummary(ocr?.amount, ocr?.date),
        "¿Confirmás?",
        [
          { id: "final_confirm", text: "✅ Confirmar" },
          { id: "final_cancel", text: "❌ Cancelar" },
        ]
      );
      return;
    }

    if (buttonId === "service_mode_specific") {
      const activeServices = await getActiveServices();
      if (activeServices.length === 0) {
        await clearSession(senderPhone);
        await sendText(groupJid, "No hay servicios activos configurados.");
        return;
      }

      const buttons = activeServices.slice(0, 3).map((service) => ({
        id: `svc_${service.id}`,
        text: service.nombre,
      }));
      if (activeServices.length > 3) {
        buttons.push({ id: "svc_otro", text: "Otro" });
      }

      await setSession(senderPhone, "awaiting_specific_service_select", {
        ...context,
        selectedPaymentType: "servicio",
        selectedServicePaymentMode: "specific",
      });

      await sendButtons(
        groupJid,
        "¿Para qué servicio es este pago especifico?",
        `Monto: $${context.ocrData?.amount?.toLocaleString("es-AR") ?? "?"}`,
        buttons
      );
      return;
    }
  }

  if (state === "awaiting_specific_service_select") {
    if (buttonId === "pay_cancel") {
      await clearSession(senderPhone);
      await sendText(groupJid, "Operación cancelada.");
      return;
    }

    // Service selected (svc_123)
    if (buttonId.startsWith("svc_") && buttonId !== "svc_otro") {
      const serviceId = parseInt(buttonId.replace("svc_", ""), 10);
      const activeServices = await getActiveServices();
      const service = activeServices.find((s) => s.id === serviceId);

      if (!service) {
        await sendText(groupJid, "Servicio no encontrado.");
        return;
      }

      await setSession(senderPhone, "awaiting_confirm", {
        ...context,
        selectedServicePaymentMode: "specific",
        selectedServiceId: serviceId,
        selectedServiceName: service.nombre,
      });

      const ocr = context.ocrData;
      await sendButtons(
        groupJid,
        specificServiceSummary(service.nombre, ocr?.amount, ocr?.date),
        "¿Confirmás?",
        [
          { id: "final_confirm", text: "✅ Confirmar" },
          { id: "final_cancel", text: "❌ Cancelar" },
        ]
      );
      return;
    }

    if (buttonId === "svc_otro") {
      await clearSession(senderPhone);
      await sendText(
        groupJid,
        "Por favor describí el pago como texto: BOT registrar pago $[monto] [servicio] [fecha]"
      );
      return;
    }
  }

  // ── awaiting_confirm: final confirmation ──
  if (state === "awaiting_confirm") {
    if (buttonId === "final_cancel") {
      await clearSession(senderPhone);
      await sendText(groupJid, "Operación cancelada.");
      return;
    }

    if (buttonId === "final_confirm") {
      const ocr = context.ocrData;
      const monto = ocr?.amount ?? 0;
      const fecha = ocr?.date ?? new Date().toISOString().slice(0, 10);
      const creadoPor = uploaderLabel(senderName);

      let result: string;

      if (context.selectedPaymentType === "alquiler") {
        const periodo = fecha.slice(0, 7);
        result = await executeTool("registrar_pago_alquiler", {
          periodo,
          monto,
          fecha_pago: fecha,
          notas: "Comprobante subido via WhatsApp.",
          creado_por: creadoPor,
          proof_urls: context.imageUrl ? [context.imageUrl] : [],
        });
      } else {
        result = await executeTool("registrar_pago_servicio", {
          monto,
          fecha_pago: fecha,
          notas:
            context.selectedServicePaymentMode === "specific"
              ? `Comprobante subido para ${context.selectedServiceName ?? "servicio"} via WhatsApp.`
              : "Comprobante subido para servicios via WhatsApp.",
          creado_por: creadoPor,
          payment_mode: context.selectedServicePaymentMode ?? "global",
          service_id: context.selectedServiceId,
          service_name: context.selectedServiceName,
          proof_urls: context.imageUrl ? [context.imageUrl] : [],
        });
      }

      await clearSession(senderPhone);
      await sendText(groupJid, `✅ ${result}`);
      return;
    }
  }

  // Unknown state / button combo
  await sendText(
    groupJid,
    "No entendí esa respuesta. Si necesitás ayuda escribí BOT ayuda."
  );

  } finally {
    if (presenceInterval) clearInterval(presenceInterval);
    await sendPresence(groupJid, "paused");
  }
}
