import { placeholderSrc } from "@/lib/placeholder";

export type VideoSidebarCategoryId =
  | "all"
  | "animation"
  | "intros"
  | "editing"
  | "invitation"
  | "holiday"
  | "slideshow"
  | "presentations"
  | "social"
  | "ads"
  | "sales"
  | "music";

export type AspectRatioFilter =
  | "all"
  | "widescreen"
  | "portrait"
  | "square"
  | "fourFive";

export type DurationFilter = "all" | "flexible" | "fixed";

export type RefineType = "templates" | "packs";

export interface VideoSidebarCategory {
  id: VideoSidebarCategoryId;
  label: string;
}

export const VIDEO_SIDEBAR_CATEGORIES: VideoSidebarCategory[] = [
  { id: "all", label: "All Templates" },
  { id: "animation", label: "Animation Videos" },
  { id: "intros", label: "Intros and Logos" },
  { id: "editing", label: "Video Editing" },
  { id: "invitation", label: "Invitation Videos" },
  { id: "holiday", label: "Holiday Videos" },
  { id: "slideshow", label: "Slideshow" },
  { id: "presentations", label: "Presentations" },
  { id: "social", label: "Social Media Videos" },
  { id: "ads", label: "Video Ad Templates" },
  { id: "sales", label: "Sales Videos" },
  { id: "music", label: "Music Visualization" },
];

export const ASPECT_RATIO_OPTIONS: {
  id: AspectRatioFilter;
  label: string;
}[] = [
  { id: "all", label: "All Sizes" },
  { id: "widescreen", label: "16:9" },
  { id: "portrait", label: "9:16" },
  { id: "square", label: "1:1" },
  { id: "fourFive", label: "4:5" },
];

export type TemplateDetailAspectRatio = "16:9" | "1:1" | "9:16";

/** A concrete aspect-ratio variant of a template — maps an aspect to the content
 *  project (UUID) the studio copies its scenes from. */
export interface TemplateVariant {
  aspect: TemplateDetailAspectRatio;
  projectId: string;
}

export const TEMPLATE_STYLE_COUNT = 4;

export interface VideoCatalogTemplate {
  id: string;
  name: string;
  videoCategory: Exclude<VideoSidebarCategoryId, "all">;
  aspectRatio: Exclude<AspectRatioFilter, "all">;
  aspectRatios?: readonly TemplateDetailAspectRatio[];
  /** Real aspect variants (with the content project id to copy). Empty for demo
   *  templates. When present, drives the aspect picker + which variant is built. */
  variants?: TemplateVariant[];
  durationType: "flexible" | "fixed";
  premium: boolean;
  sceneCount: number;
  supports4k: boolean;
  colorChange: boolean;
  scriptToVideo: boolean;
  description?: string;
  isNew?: boolean;
}

export function getVideoTemplateCategoryLabel(
  category: Exclude<VideoSidebarCategoryId, "all">
): string {
  const match = VIDEO_SIDEBAR_CATEGORIES.find((item) => item.id === category);
  return match?.label ?? category;
}

export function getTemplateDetailAspectRatios(
  template: VideoCatalogTemplate
): TemplateDetailAspectRatio[] {
  // Real variants take precedence so the picker reflects what can actually be built.
  if (template.variants && template.variants.length > 0) {
    return template.variants.map((v) => v.aspect);
  }
  if (template.aspectRatios && template.aspectRatios.length > 0) {
    return [...template.aspectRatios];
  }
  return ["16:9", "9:16"];
}

export function getVideoTemplateStyleImageSrc(
  templateId: string,
  styleIndex: number
): string {
  return placeholderSrc(`${templateId}-style${styleIndex}`, 240, 135);
}

export function getVideoTemplateExampleImageSrc(
  templateId: string,
  exampleIndex: number
): string {
  return placeholderSrc(`${templateId}-example${exampleIndex}`, 520, 325);
}

const templatesByCategory: Record<
  Exclude<VideoSidebarCategoryId, "all">,
  string[]
> = {
  animation: [
    "Whiteboard Animation Toolkit",
    "3D Explainer Video Toolkit",
    "Trendy Explainer Toolkit",
    "Factory of 3D Animations",
    "Anime Stories Pack",
    "Healthcare Explainer Toolkit",
  ],
  intros: [
    "Abstract Distortion Intro",
    "Glossy Bubbles Intro",
    "Neon Soundwaves Visualizer",
    "Minimal Logo Reveal",
    "Glitch Intro Pack",
  ],
  editing: [
    "Cinematic Color Grade",
    "Quick Cut Montage",
    "Documentary Style Opener",
  ],
  invitation: [
    "Wedding Invitation Slideshow",
    "Birthday Party Invite",
    "Corporate Event Opening",
  ],
  holiday: [
    "Christmas Greeting Card",
    "New Year Countdown",
    "Seasonal Sale Promo",
  ],
  slideshow: [
    "Polaroid Frames Slideshow",
    "Flipping Slideshow",
    "Fragmented Transitions Slideshow",
    "Parallax Circles",
    "Bokeh Effects Slideshow",
  ],
  presentations: [
    "Business Presentation Pack",
    "Startup Pitch Deck",
    "Quarterly Report Intro",
  ],
  social: [
    "Instagram Carousel",
    "TikTok Hook Pack",
    "Story Highlight Reel",
    "LinkedIn Promo",
  ],
  ads: [
    "Product Launch Ad",
    "App Promo Vertical",
    "Flash Sale Countdown",
  ],
  sales: [
    "SaaS Explainer",
    "Real Estate Walkthrough",
    "Restaurant Promo",
  ],
  music: [
    "Audio Spectrum Visualizer",
    "Vinyl Record Spin",
    "Beat Sync Typography",
  ],
};

const aspectRatios: Exclude<AspectRatioFilter, "all">[] = [
  "widescreen",
  "portrait",
  "square",
  "fourFive",
];

function buildVideoCatalog(): VideoCatalogTemplate[] {
  const items: VideoCatalogTemplate[] = [];
  let index = 0;

  for (const [category, names] of Object.entries(templatesByCategory)) {
    const videoCategory = category as Exclude<VideoSidebarCategoryId, "all">;
    for (const baseName of names) {
      for (let variant = 0; variant < 2; variant += 1) {
        const name = variant > 0 ? `${baseName} ${variant + 1}` : baseName;
        const detailAspectRatios: TemplateDetailAspectRatio[] =
          index % 3 === 0 ? ["16:9"] : ["16:9", "9:16"];
        items.push({
          id: `vtpl-${category}-${index}`,
          name,
          videoCategory,
          aspectRatio: aspectRatios[index % aspectRatios.length],
          aspectRatios: detailAspectRatios,
          durationType: index % 3 === 0 ? "fixed" : "flexible",
          premium: index % 4 === 0,
          sceneCount: 5 + (index % 12) * 10,
          supports4k: index % 2 === 0,
          colorChange: index % 3 !== 0,
          scriptToVideo: index % 5 === 0,
          isNew: index < 8,
        });
        index += 1;
      }
    }
  }

  return items;
}

/** Featured presets on /studio/video/new — ids match TEMPLATE_GALLERY_ITEMS */
const ONBOARDING_PRESET_TEMPLATES: VideoCatalogTemplate[] = [
  {
    id: "promo-reel",
    name: "Animated Inspirational Video",
    videoCategory: "animation",
    aspectRatio: "widescreen",
    aspectRatios: ["16:9", "9:16"],
    durationType: "flexible",
    premium: false,
    sceneCount: 12,
    supports4k: true,
    colorChange: true,
    scriptToVideo: false,
    isNew: true,
  },
  {
    id: "product-launch",
    name: "Cybersecurity Company Promo",
    videoCategory: "ads",
    aspectRatio: "widescreen",
    aspectRatios: ["16:9", "9:16"],
    durationType: "flexible",
    premium: true,
    sceneCount: 8,
    supports4k: true,
    colorChange: true,
    scriptToVideo: false,
  },
  {
    id: "brand-story",
    name: "Get to Know Your Customers Day",
    videoCategory: "social",
    aspectRatio: "widescreen",
    aspectRatios: ["16:9", "9:16"],
    durationType: "flexible",
    premium: false,
    sceneCount: 10,
    supports4k: false,
    colorChange: true,
    scriptToVideo: true,
  },
  {
    id: "instagram-carousel",
    name: "SEO Agency Introduction",
    videoCategory: "social",
    aspectRatio: "square",
    aspectRatios: ["16:9", "9:16"],
    durationType: "flexible",
    premium: false,
    sceneCount: 6,
    supports4k: false,
    colorChange: true,
    scriptToVideo: false,
  },
  {
    id: "tiktok-hook",
    name: "Tech Startup Promo",
    videoCategory: "social",
    aspectRatio: "portrait",
    aspectRatios: ["9:16"],
    durationType: "flexible",
    premium: false,
    sceneCount: 5,
    supports4k: false,
    colorChange: true,
    scriptToVideo: false,
    isNew: true,
  },
  {
    id: "pitch-deck",
    name: "Corporate Explainer",
    videoCategory: "presentations",
    aspectRatio: "widescreen",
    aspectRatios: ["16:9"],
    durationType: "fixed",
    premium: false,
    sceneCount: 15,
    supports4k: true,
    colorChange: true,
    scriptToVideo: false,
  },
  {
    id: "hero-promo",
    name: "Hero Product Launch",
    videoCategory: "ads",
    aspectRatio: "widescreen",
    aspectRatios: ["16:9", "9:16"],
    durationType: "flexible",
    premium: true,
    sceneCount: 9,
    supports4k: true,
    colorChange: true,
    scriptToVideo: false,
  },
  {
    id: "event-recap",
    name: "Event Recap Highlight",
    videoCategory: "slideshow",
    aspectRatio: "widescreen",
    aspectRatios: ["16:9", "9:16"],
    durationType: "flexible",
    premium: false,
    sceneCount: 11,
    supports4k: true,
    colorChange: true,
    scriptToVideo: false,
  },
];

export const VIDEO_TEMPLATES_CATALOG = [
  ...ONBOARDING_PRESET_TEMPLATES,
  ...buildVideoCatalog(),
];

export interface VideoTemplateFilters {
  search: string;
  sidebarCategory: VideoSidebarCategoryId;
  aspectRatio: AspectRatioFilter;
  duration: DurationFilter;
  premiumOnly: boolean;
  supports4k: boolean;
  colorChange: boolean;
  scriptToVideo: boolean;
}

export function filterVideoCatalog(
  templates: VideoCatalogTemplate[],
  filters: VideoTemplateFilters
): VideoCatalogTemplate[] {
  const query = filters.search.trim().toLowerCase();

  return templates.filter((template) => {
    if (
      filters.sidebarCategory !== "all" &&
      template.videoCategory !== filters.sidebarCategory
    ) {
      return false;
    }
    if (
      filters.aspectRatio !== "all" &&
      template.aspectRatio !== filters.aspectRatio
    ) {
      return false;
    }
    if (
      filters.duration !== "all" &&
      template.durationType !== filters.duration
    ) {
      return false;
    }
    if (filters.premiumOnly && !template.premium) return false;
    if (filters.supports4k && !template.supports4k) return false;
    if (filters.colorChange && !template.colorChange) return false;
    if (filters.scriptToVideo && !template.scriptToVideo) return false;
    if (query && !template.name.toLowerCase().includes(query)) return false;
    return true;
  });
}

export function getVideoTemplateImageSrc(id: string): string {
  return placeholderSrc(id, 640, 360);
}

export interface VideoTemplateSection {
  id: string;
  title: string;
  count: number;
  templates: VideoCatalogTemplate[];
}

export function buildVideoTemplateSections(
  filtered: VideoCatalogTemplate[],
  sidebarCategory: VideoSidebarCategoryId
): VideoTemplateSection[] {
  const newlyReleased = filtered.filter((t) => t.isNew).slice(0, 8);
  const sections: VideoTemplateSection[] = [];

  if (newlyReleased.length > 0 && sidebarCategory === "all") {
    sections.push({
      id: "newly-released",
      title: "Newly released",
      count: newlyReleased.length,
      templates: newlyReleased,
    });
  }

  const categories =
    sidebarCategory === "all"
      ? VIDEO_SIDEBAR_CATEGORIES.filter((c) => c.id !== "all")
      : VIDEO_SIDEBAR_CATEGORIES.filter((c) => c.id === sidebarCategory);

  for (const category of categories) {
    const templates = filtered
      .filter((t) => t.videoCategory === category.id)
      .slice(0, 12);
    if (templates.length === 0) continue;
    sections.push({
      id: category.id,
      title: category.label,
      count: filtered.filter((t) => t.videoCategory === category.id).length,
      templates,
    });
  }

  return sections;
}

export function toProjectTemplate(
  template: VideoCatalogTemplate
): { id: string; name: string; category: "Video" } {
  return {
    id: template.id,
    name: template.name,
    category: "Video",
  };
}

// ── Admin API → catalog helpers ───────────────────────────────────────────────

/**
 * Map an admin category name (or slug) to the closest hardcoded
 * VideoSidebarCategoryId. Falls back to "social" when nothing matches.
 */
export function adminCategoryNameToSidebarId(
  categoryName?: string
): Exclude<VideoSidebarCategoryId, "all"> {
  if (!categoryName) return "social";
  const n = categoryName.toLowerCase();
  if (n.includes("animat")) return "animation";
  if (n.includes("intro") || n.includes("logo")) return "intros";
  if (n.includes("edit")) return "editing";
  if (n.includes("invit")) return "invitation";
  if (
    n.includes("holiday") ||
    n.includes("christmas") ||
    n.includes("new year")
  )
    return "holiday";
  if (n.includes("slide")) return "slideshow";
  if (
    n.includes("present") ||
    n.includes("pitch") ||
    n.includes("deck")
  )
    return "presentations";
  if (
    n.includes("social") ||
    n.includes("instagram") ||
    n.includes("tiktok") ||
    n.includes("reel")
  )
    return "social";
  if (n.includes("ad") || n.includes("promo") || n.includes("ads"))
    return "ads";
  if (n.includes("sale") || n.includes("real estate")) return "sales";
  if (n.includes("music") || n.includes("audio")) return "music";
  return "social";
}

/**
 * Convert a raw AdminProject (from admin-api.ts) to a VideoCatalogTemplate
 * so admin-managed templates can be shown on the templates page.
 *
 * Import type only — do not import from admin-api in this file at runtime.
 */
export interface AdminProjectLike {
  slug: string;
  title: string;
  description?: string;
  type: "video" | "image";
  categoryName?: string;
  coverImageUrl?: string;
  previewVideoUrl?: string;
}

export function adminProjectToCatalogTemplate(
  p: AdminProjectLike
): VideoCatalogTemplate {
  return {
    id: p.slug,
    name: p.title,
    videoCategory: adminCategoryNameToSidebarId(p.categoryName),
    aspectRatio: "widescreen",
    durationType: "flexible",
    premium: false,
    sceneCount: 0,
    supports4k: false,
    colorChange: false,
    scriptToVideo: false,
    description: p.description,
    isNew: true,
  };
}
