import { Types } from "mongoose";
import UserModel from "../models/UserModel";
import SmartcarAccountModel from "../models/SmartcarAccountModel";
import VehicleModel from "../models/vehicleModel";

const TAG = "[Smartcar Webhook]";

/**
 * When Smartcar delivers webhook payloads, ensure `User.isCarsRegistered` is true when we can tie
 * the payload to a Tank user via SmartcarAccount or Vehicle. VERIFY is handled in the webhook route.
 *
 * Any delivery with `user.id` and/or Smartcar vehicle id is considered (broader than VEHICLE_* only).
 */
export async function syncIsCarsRegisteredFromDelivery(
  body: Record<string, unknown>,
): Promise<void> {
  const eventType =
    typeof body.eventType === "string" ? body.eventType.toUpperCase() : "";
  if (eventType === "VERIFY") return;

  console.log(
    "[Smartcar][DEBUG] WEBHOOK syncIsCarsRegistered — eventType=%s",
    eventType || "(unknown)",
  );

  const data =
    body.data && typeof body.data === "object"
      ? (body.data as Record<string, unknown>)
      : null;

  let smartcarUserId = "";
  if (data?.user && typeof data.user === "object") {
    const id = (data.user as Record<string, unknown>).id;
    if (typeof id === "string" && id.length > 0) smartcarUserId = id.trim();
  }

  if (!smartcarUserId && body.meta && typeof body.meta === "object") {
    const m = body.meta as Record<string, unknown>;
    const mu = m.user ?? m.smartcarUser ?? m.smartcar_user;
    if (mu && typeof mu === "object") {
      const id = (mu as Record<string, unknown>).id;
      if (typeof id === "string" && id.length > 0) smartcarUserId = id.trim();
    }
  }

  let smartcarVehicleId =
    typeof body.vehicleId === "string" ? body.vehicleId.trim() : "";

  if (!smartcarVehicleId && data?.vehicle && typeof data.vehicle === "object") {
    const vid = (data.vehicle as Record<string, unknown>).id;
    if (typeof vid === "string") smartcarVehicleId = vid.trim();
  }

  console.log(
    "[Smartcar][DEBUG] WEBHOOK — parsed smartcarUserId=%s smartcarVehicleId=%s",
    smartcarUserId ? smartcarUserId.slice(0, 8) + "…" : "(none)",
    smartcarVehicleId ? smartcarVehicleId.slice(0, 8) + "…" : "(none)",
  );

  if (!smartcarUserId && !smartcarVehicleId) {
    console.warn(
      "[Smartcar][DEBUG] WEBHOOK — no userId or vehicleId in payload, skipping",
    );
    return;
  }

  let mongoUserId: string | null = null;

  if (smartcarUserId) {
    const acc = await SmartcarAccountModel.findOne({
      smartcarUserId,
      status: true,
    })
      .select("userId")
      .lean();
    if (acc?.userId) {
      mongoUserId = String(acc.userId);
      console.log(
        "[Smartcar][DEBUG] WEBHOOK — resolved Tank user via SmartcarAccount: %s",
        mongoUserId.slice(0, 8) + "…",
      );
    } else {
      console.warn(
        "[Smartcar][DEBUG] WEBHOOK — SmartcarAccount found but NO userId linked (complete-connect not called yet?)",
      );
    }
  }

  if (!mongoUserId && smartcarVehicleId) {
    const v = await VehicleModel.findOne({
      smartcarVehicleId,
      isDeleted: false,
    })
      .select("userId")
      .lean();
    if (v?.userId) {
      mongoUserId = String(v.userId);
      console.log(
        "[Smartcar][DEBUG] WEBHOOK — resolved Tank user via VehicleModel: %s",
        mongoUserId.slice(0, 8) + "…",
      );
    }
  }

  if (!mongoUserId || !Types.ObjectId.isValid(mongoUserId)) {
    console.warn(
      `${TAG}[DEBUG] WEBHOOK — NO Tank Track user mapped (event=${eventType || "?"}, vehicleId=${smartcarVehicleId || "—"}, userId=${smartcarUserId || "—"}). User must complete-connect first.`,
    );
    return;
  }

  let smartcarUserIdForUser = smartcarUserId;
  if (!smartcarUserIdForUser && smartcarVehicleId) {
    const v = await VehicleModel.findOne({
      smartcarVehicleId,
      isDeleted: false,
    })
      .select("smartcarUserId")
      .lean();
    const su = v?.smartcarUserId;
    if (typeof su === "string" && su.trim()) smartcarUserIdForUser = su.trim();
  }

  const $set: Record<string, unknown> = { isCarsRegistered: true };
  if (smartcarUserIdForUser) {
    $set.smartcarToken = smartcarUserIdForUser;
  }

  await UserModel.findByIdAndUpdate(new Types.ObjectId(mongoUserId), { $set });
  console.log(
    "[Smartcar][DEBUG] WEBHOOK — isCarsRegistered=true SET ✓ for user=%s",
    mongoUserId.slice(0, 8) + "…",
  );
}
