import {
  deleteCloudinaryImageByUrl,
  verifyCloudinaryWebhookSignature,
} from "~/lib/cloudinary.server";
import { logger } from "~/lib/logger";
import { findTeamById, updateTeam } from "~/models/team";
import { findUserById, updateUser } from "~/models/user";
import type { Route } from "./+types/api.webhooks.cloudinary";

type CloudinaryContext = Record<string, unknown> | string | undefined;

interface CloudinaryWebhookPayload {
  secure_url?: string;
  moderation?: Array<{ status?: string }>;
  moderation_status?: string;
  info?: {
    moderation?: { status?: string } | Array<{ status?: string }>;
  };
  context?: CloudinaryContext | { custom?: Record<string, unknown> };
}

function getContextValue(context: CloudinaryWebhookPayload["context"], key: string): string | null {
  if (!context) return null;

  if (typeof context === "string") {
    const pairs = context.split("|").map((part) => part.split("="));
    const found = pairs.find(([pairKey]) => pairKey === key);
    return found?.[1] ?? null;
  }

  const custom = "custom" in context && context.custom && typeof context.custom === "object"
    ? context.custom
    : context;
  const value = (custom as Record<string, unknown>)[key];
  return typeof value === "string" ? value : null;
}

function moderationStatus(payload: CloudinaryWebhookPayload): string | null {
  const direct = payload.moderation?.[0]?.status ?? payload.moderation_status;
  if (direct) return direct;

  const infoModeration = payload.info?.moderation;
  if (Array.isArray(infoModeration)) return infoModeration[0]?.status ?? null;
  return infoModeration?.status ?? null;
}

export async function action({ request }: Route.ActionArgs) {
  const body = await request.text();
  const signature = request.headers.get("X-Cld-Signature");
  const timestamp = request.headers.get("X-Cld-Timestamp");

  if (!verifyCloudinaryWebhookSignature({ body, signature, timestamp })) {
    return Response.json({ error: "Invalid signature" }, { status: 401 });
  }

  let payload: CloudinaryWebhookPayload;
  try {
    payload = JSON.parse(body) as CloudinaryWebhookPayload;
  } catch {
    return Response.json({ error: "Invalid JSON" }, { status: 400 });
  }

  const status = moderationStatus(payload);
  if (status !== "approved") {
    logger.info("Cloudinary avatar not approved:", { status });
    return Response.json({ status: "ignored" });
  }

  if (!payload.secure_url) {
    return Response.json({ error: "Missing secure_url" }, { status: 400 });
  }

  const target = getContextValue(payload.context, "avatar_target");
  const entityId = getContextValue(payload.context, "entity_id");

  if (!target || !entityId) {
    return Response.json({ error: "Missing avatar context" }, { status: 400 });
  }

  if (target === "user") {
    const existingUser = await findUserById(entityId);
    await updateUser(entityId, {
      customAvatarUrl: payload.secure_url,
      avatarType: "uploaded",
    });
    if (existingUser?.customAvatarUrl && existingUser.customAvatarUrl !== payload.secure_url) {
      deleteCloudinaryImageByUrl(existingUser.customAvatarUrl).catch((error) => {
        logger.error("Failed to delete replaced user avatar from Cloudinary:", error);
      });
    }
    return Response.json({ status: "updated" });
  }

  if (target === "team") {
    const existingTeam = await findTeamById(entityId);
    await updateTeam(entityId, {
      logoUrl: payload.secure_url,
      avatarType: "uploaded",
    });
    if (existingTeam?.logoUrl && existingTeam.logoUrl !== payload.secure_url) {
      deleteCloudinaryImageByUrl(existingTeam.logoUrl).catch((error) => {
        logger.error("Failed to delete replaced team avatar from Cloudinary:", error);
      });
    }
    return Response.json({ status: "updated" });
  }

  return Response.json({ error: "Unknown avatar target" }, { status: 400 });
}
