/**
 * Pre-publish content validation against platform media rules.
 */

import {
  getPlatformCapability,
  type SocialPlatformId,
} from "@/lib/social/config/platform-registry";
import { resolvePlatformCountryAvailability } from "@/lib/social/config/platform-availability";
import { getPlatformBlockReason } from "@/lib/social/config/social-config";

export interface PublishValidationInput {
  platform: string;
  caption?: string;
  imageUrl?: string | null;
  videoUrl?: string | null;
  videoDurationSeconds?: number | null;
  imageBytes?: number | null;
  videoBytes?: number | null;
  imageMime?: string | null;
  videoMime?: string | null;
  projectCountries?: string[] | null;
}

export interface PublishValidationIssue {
  code: string;
  message: string;
  field?: string;
}

export interface PublishValidationResult {
  ok: boolean;
  platform: string;
  issues: PublishValidationIssue[];
}

export function validateContentForPlatform(
  input: PublishValidationInput,
): PublishValidationResult {
  const platform = input.platform as SocialPlatformId;
  const issues: PublishValidationIssue[] = [];
  const cap = getPlatformCapability(platform);

  if (!cap) {
    return {
      ok: false,
      platform,
      issues: [{ code: "UNKNOWN_PLATFORM", message: `Unknown platform: ${input.platform}` }],
    };
  }

  const block = getPlatformBlockReason(platform);
  if (block) {
    issues.push({ code: block.code, message: block.message });
  }

  const country = resolvePlatformCountryAvailability(platform, input.projectCountries);
  if (!country.available && country.reason !== "missing_credentials") {
    // missing_credentials already covered by block reason when applicable
    if (country.reason === "country_blocked" || country.reason === "country_unsupported") {
      issues.push({
        code: country.reason.toUpperCase(),
        message: country.message,
      });
    }
  }

  const rules = cap.mediaRules;
  const caption = input.caption?.trim() ?? "";
  if (caption.length > rules.maxCaptionLength) {
    issues.push({
      code: "CAPTION_TOO_LONG",
      message: `Caption exceeds ${cap.label} limit of ${rules.maxCaptionLength} characters (got ${caption.length}).`,
      field: "caption",
    });
  }

  const hasCaption = caption.length > 0;
  const hasImage = Boolean(input.imageUrl?.trim());
  const hasVideo = Boolean(input.videoUrl?.trim());

  const present = new Set<string>();
  if (hasCaption) present.add("caption");
  if (hasImage) present.add("image");
  if (hasVideo) present.add("video");

  const meetsRequirement = rules.requiresAnyOf.some((r) => present.has(r));
  if (!meetsRequirement) {
    issues.push({
      code: "MISSING_REQUIRED_MEDIA",
      message: `${cap.label} requires one of: ${rules.requiresAnyOf.join(", ")}.`,
    });
  }

  if (rules.video?.required && !hasVideo) {
    issues.push({
      code: "VIDEO_REQUIRED",
      message: `${cap.label} requires a video file.`,
      field: "video",
    });
  }

  if (hasImage && rules.image) {
    if (input.imageMime && !rules.image.mimeTypes.includes(input.imageMime)) {
      issues.push({
        code: "IMAGE_TYPE_UNSUPPORTED",
        message: `${cap.label} does not accept ${input.imageMime}. Allowed: ${rules.image.mimeTypes.join(", ")}.`,
        field: "image",
      });
    }
    if (
      typeof input.imageBytes === "number" &&
      rules.image.maxBytes &&
      input.imageBytes > rules.image.maxBytes
    ) {
      issues.push({
        code: "IMAGE_TOO_LARGE",
        message: `Image exceeds ${cap.label} size limit.`,
        field: "image",
      });
    }
  }

  if (hasVideo && rules.video) {
    if (input.videoMime && !rules.video.mimeTypes.includes(input.videoMime)) {
      issues.push({
        code: "VIDEO_TYPE_UNSUPPORTED",
        message: `${cap.label} does not accept ${input.videoMime}. Allowed: ${rules.video.mimeTypes.join(", ")}.`,
        field: "video",
      });
    }
    if (
      typeof input.videoDurationSeconds === "number" &&
      rules.video.maxDurationSeconds &&
      input.videoDurationSeconds > rules.video.maxDurationSeconds
    ) {
      issues.push({
        code: "VIDEO_TOO_LONG",
        message: `Video exceeds ${cap.label} max duration of ${rules.video.maxDurationSeconds}s.`,
        field: "video",
      });
    }
    if (
      typeof input.videoDurationSeconds === "number" &&
      rules.video.minDurationSeconds &&
      input.videoDurationSeconds < rules.video.minDurationSeconds
    ) {
      issues.push({
        code: "VIDEO_TOO_SHORT",
        message: `Video is shorter than ${cap.label} minimum of ${rules.video.minDurationSeconds}s.`,
        field: "video",
      });
    }
  }

  // Pinterest / Instagram require image when that's the only supported path
  if (platform === "pinterest" && !hasImage) {
    issues.push({
      code: "IMAGE_REQUIRED",
      message: "Pinterest requires an image to create a Pin.",
      field: "image",
    });
  }
  if (platform === "instagram" && !hasImage) {
    issues.push({
      code: "IMAGE_REQUIRED",
      message: "Instagram requires an image for publishing in this release.",
      field: "image",
    });
  }

  return { ok: issues.length === 0, platform, issues };
}

export function validateContentForPlatforms(
  platforms: string[],
  input: Omit<PublishValidationInput, "platform">,
): PublishValidationResult[] {
  return platforms.map((platform) =>
    validateContentForPlatform({ ...input, platform }),
  );
}
