// Structured homepage section types. Each type maps to a fixed layout component that follows the
// reference composition, so editors change content without breaking the design.

export type FieldKind = "text" | "textarea" | "image" | "link" | "product" | "products" | "category" | "group" | "list" | "boolean";

export type FieldDef = {
  key: string;
  label: string;
  kind: FieldKind;
  help?: string;
  fields?: FieldDef[]; // for group / list
  min?: number; // list length
  max?: number;
  required?: boolean;
};

export type SectionDef = { type: string; name: string; description: string; fields: FieldDef[] };

const panel: FieldDef[] = [
  { key: "image", label: "Image", kind: "image", required: true },
  { key: "hoverImage", label: "Image on hover", kind: "image" },
  { key: "alt", label: "Alt text", kind: "text" },
  { key: "href", label: "Link", kind: "link" },
];

const cta: FieldDef[] = [
  { key: "ctaLabel", label: "Button label", kind: "text" },
  { key: "ctaHref", label: "Button link", kind: "link" },
];

export const SECTION_DEFS: Record<string, SectionDef> = {
  CATEGORY_FEATURE: {
    type: "CATEGORY_FEATURE",
    name: "Category feature (4 portrait panels + title)",
    description: "Four tall images in a row, each swapping to a second image on hover, with a large category title link below.",
    fields: [
      { key: "title", label: "Title", kind: "text", required: true },
      { key: "href", label: "Title link", kind: "link", required: true },
      { key: "panels", label: "Panels", kind: "list", min: 2, max: 4, fields: panel },
    ],
  },
  EDITORIAL_TRIPTYCH: {
    type: "EDITORIAL_TRIPTYCH",
    name: "Editorial triptych",
    description: "Monogram, one large image beside two tall images, then a short text block.",
    fields: [
      { key: "large", label: "Large image", kind: "image", required: true },
      { key: "smallA", label: "Tall image 1", kind: "image" },
      { key: "smallB", label: "Tall image 2", kind: "image" },
      { key: "title", label: "Title", kind: "text" },
      { key: "body", label: "Text", kind: "textarea" },
      ...cta,
    ],
  },
  PRODUCT_STORIES: {
    type: "PRODUCT_STORIES",
    name: "Product stories",
    description: "Alternating product images with batch details and a paragraph about the piece.",
    fields: [
      { key: "title", label: "Section title", kind: "text" },
      {
        key: "stories", label: "Stories", kind: "list", min: 1, max: 4,
        fields: [
          { key: "productId", label: "Product", kind: "product", required: true },
          { key: "caption", label: "Caption under the product name", kind: "text" },
          { key: "body", label: "Text", kind: "textarea" },
          ...cta,
        ],
      },
    ],
  },
  CATEGORY_INDEX: {
    type: "CATEGORY_INDEX",
    name: "Category index",
    description: "Large list of categories; hovering a name reveals its image.",
    fields: [
      { key: "items", label: "Entries", kind: "list", min: 1, max: 10, fields: [
        { key: "label", label: "Label", kind: "text", required: true },
        { key: "href", label: "Link", kind: "link", required: true },
        { key: "image", label: "Image", kind: "image" },
      ] },
    ],
  },
  LIMITED_DROP: {
    type: "LIMITED_DROP",
    name: "Limited pre-order drop",
    description: "A titled block with an introduction and a strip of pre-order products showing live batch status.",
    fields: [
      { key: "title", label: "Title", kind: "text", required: true },
      { key: "lead", label: "Lead sentence", kind: "textarea" },
      { key: "body", label: "Text", kind: "textarea" },
      ...cta,
      { key: "productIds", label: "Products", kind: "products", max: 8 },
      { key: "footnote", label: "Closing text", kind: "textarea" },
    ],
  },
  ENQUIRY_MARQUEE: {
    type: "ENQUIRY_MARQUEE",
    name: "Styling enquiry with image marquee",
    description: "Slowly scrolling image strip with a text block and a call to action.",
    fields: [
      { key: "title", label: "Title", kind: "text", required: true },
      { key: "body", label: "Text", kind: "textarea" },
      ...cta,
      { key: "images", label: "Images", kind: "list", min: 3, max: 10, fields: [{ key: "image", label: "Image", kind: "image", required: true }, { key: "alt", label: "Alt text", kind: "text" }] },
    ],
  },
  BRAND_STORY: {
    type: "BRAND_STORY",
    name: "Brand story",
    description: "Image beside a title, a bold lead and supporting paragraphs.",
    fields: [
      { key: "title", label: "Title", kind: "text", required: true },
      { key: "lead", label: "Lead", kind: "textarea" },
      { key: "body", label: "Text", kind: "textarea" },
      { key: "image", label: "Image", kind: "image" },
      ...cta,
    ],
  },
  GIFTING: {
    type: "GIFTING",
    name: "Gifting / guide",
    description: "Centred title and paragraph with a wide image.",
    fields: [
      { key: "title", label: "Title", kind: "text", required: true },
      { key: "body", label: "Text", kind: "textarea" },
      ...cta,
      { key: "image", label: "Wide image", kind: "image" },
    ],
  },
  FOOTER_GALLERY: {
    type: "FOOTER_GALLERY",
    name: "Image strip",
    description: "Edge-to-edge horizontal strip of images above the footer.",
    fields: [{ key: "images", label: "Images", kind: "list", min: 2, max: 10, fields: [{ key: "image", label: "Image", kind: "image", required: true }, { key: "alt", label: "Alt text", kind: "text" }] }],
  },
  NEWSLETTER: {
    type: "NEWSLETTER",
    name: "Drop notifications sign-up",
    description: "Large sentence with an email sign-up.",
    fields: [
      { key: "title", label: "Title", kind: "text", required: true },
      { key: "buttonLabel", label: "Button label", kind: "text" },
    ],
  },
};

type Json = null | boolean | number | string | Json[] | { [k: string]: Json };

/** Coerces and validates section data against its field definitions. Returns cleaned data and errors. */
export function validateSection(type: string, data: unknown): { data: Record<string, Json>; errors: string[] } {
  const def = SECTION_DEFS[type];
  if (!def) return { data: {}, errors: [`Unknown section type ${type}`] };
  const errors: string[] = [];
  const clean = (fields: FieldDef[], src: unknown, path: string): Record<string, Json> => {
    const o = (src && typeof src === "object" ? src : {}) as Record<string, unknown>;
    const out: Record<string, Json> = {};
    for (const f of fields) {
      const v = o[f.key];
      const label = `${path}${f.label}`;
      switch (f.kind) {
        case "list": {
          const arr = Array.isArray(v) ? v : [];
          if (f.min && arr.length < f.min) errors.push(`${label}: add at least ${f.min}.`);
          if (f.max && arr.length > f.max) errors.push(`${label}: at most ${f.max}.`);
          out[f.key] = arr.slice(0, f.max ?? 50).map((item, i) => clean(f.fields ?? [], item, `${label} ${i + 1} › `));
          break;
        }
        case "products": {
          const arr = Array.isArray(v) ? v.filter((x) => typeof x === "string") : [];
          out[f.key] = arr.slice(0, f.max ?? 24) as string[];
          break;
        }
        case "boolean":
          out[f.key] = v === true || v === "true";
          break;
        default: {
          let s = typeof v === "string" ? v.trim() : "";
          if (f.kind === "link" && s && !/^(\/|https?:\/\/|mailto:|tel:|#)/.test(s)) { errors.push(`${label}: links must start with / or https://`); s = ""; }
          if (f.kind === "image" && s && !/^(\/|https:\/\/)/.test(s)) { errors.push(`${label}: choose an image from the media library.`); s = ""; }
          if (f.required && !s) errors.push(`${label} is required.`);
          out[f.key] = s.slice(0, f.kind === "textarea" ? 4000 : 400);
        }
      }
    }
    return out;
  };
  return { data: clean(def.fields, data, ""), errors };
}

export type SectionData = Record<string, Json>;
