import { PortfolioSectionType } from "@prisma/client";
import { z } from "zod";

import { mediaFieldInputSchema } from "./media-validation";

const requiredText = (label: string) =>
  z
    .string()
    .trim()
    .min(1, `${label} is required.`);

const optionalTrimmedText = z.string().trim().optional().transform((value) => value ?? "");
const portfolioProjectViewModes = ["GRID", "STORY", "CASE_STUDY"] as const;

export const categoryInputSchema = z.object({
  id: z.string().trim().optional(),
  slug: requiredText("Category slug")
    .regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "Category slug must be lowercase and hyphenated."),
  nameAr: requiredText("Category nameAr"),
  nameEn: requiredText("Category nameEn"),
  nameDe: requiredText("Category nameDe"),
  descriptionAr: requiredText("Category descriptionAr"),
  descriptionEn: requiredText("Category descriptionEn"),
  descriptionDe: requiredText("Category descriptionDe"),
  sortOrder: z.coerce.number().int().min(0).max(9999),
  isActive: z.boolean(),
});

export const sectionInputSchema = z
  .object({
    id: z.string().trim().optional(),
    type: z.nativeEnum(PortfolioSectionType),
    titleAr: requiredText("Section titleAr"),
    titleEn: requiredText("Section titleEn"),
    titleDe: requiredText("Section titleDe"),
    bodyAr: optionalTrimmedText,
    bodyEn: optionalTrimmedText,
    bodyDe: optionalTrimmedText,
    imagePath: optionalTrimmedText,
    media: mediaFieldInputSchema.optional(),
    linkUrl: optionalTrimmedText.refine(
      (value) => value === "" || /^https?:\/\//.test(value) || value.startsWith("/"),
      "Section linkUrl must be an absolute URL or start with /.",
    ),
    sortOrder: z.coerce.number().int().min(0).max(9999),
  })
  .superRefine((value, context) => {
    const hasBody = Boolean(value.bodyAr && value.bodyEn && value.bodyDe);
    const hasImage = value.media?.mode === "library"
      ? Boolean(value.media.assetId)
      : value.media?.mode === "upload"
        ? true
        : Boolean(value.imagePath);

    if (
      (value.type === PortfolioSectionType.RICH_TEXT ||
        value.type === PortfolioSectionType.STATS ||
        value.type === PortfolioSectionType.DELIVERABLES) &&
      !hasBody
    ) {
      context.addIssue({
        code: z.ZodIssueCode.custom,
        path: ["bodyAr"],
        message: "This section type requires body content in all languages.",
      });
    }

    if (value.type === PortfolioSectionType.GALLERY && !hasImage) {
      context.addIssue({
        code: z.ZodIssueCode.custom,
        path: ["media"],
        message: "Single image sections require an image.",
      });
    }

    if (value.type === PortfolioSectionType.LINK && !value.linkUrl) {
      context.addIssue({
        code: z.ZodIssueCode.custom,
        path: ["linkUrl"],
        message: "Link sections require a link URL.",
      });
    }
  });

export const assetInputSchema = z.object({
  id: z.string().trim().optional(),
  kind: z.literal("IMAGE"),
  filePath: optionalTrimmedText,
  fileFieldName: optionalTrimmedText,
  media: mediaFieldInputSchema.optional(),
  altAr: requiredText("Asset altAr"),
  altEn: requiredText("Asset altEn"),
  altDe: requiredText("Asset altDe"),
  sortOrder: z.coerce.number().int().min(0).max(9999),
});

export const projectInputSchema = z.object({
  id: z.string().trim().optional(),
  categoryId: requiredText("Project categoryId"),
  slug: requiredText("Project slug")
    .regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "Project slug must be lowercase and hyphenated."),
  viewMode: z.enum(portfolioProjectViewModes).default("GRID"),
  titleAr: requiredText("Project titleAr"),
  titleEn: requiredText("Project titleEn"),
  titleDe: requiredText("Project titleDe"),
  summaryAr: requiredText("Project summaryAr"),
  summaryEn: requiredText("Project summaryEn"),
  summaryDe: requiredText("Project summaryDe"),
  clientName: requiredText("Project clientName"),
  projectYear: z.coerce.number().int().min(2000).max(2100),
  serviceLabelAr: requiredText("Project serviceLabelAr"),
  serviceLabelEn: requiredText("Project serviceLabelEn"),
  serviceLabelDe: requiredText("Project serviceLabelDe"),
  previewUrl: optionalTrimmedText.refine(
    (value) => value === "" || /^https?:\/\//.test(value),
    "Project previewUrl must be an absolute URL.",
  ),
  currentCoverImagePath: optionalTrimmedText,
  coverMedia: mediaFieldInputSchema.optional(),
  sortOrder: z.coerce.number().int().min(0).max(9999),
  isFeatured: z.boolean(),
  isPublished: z.boolean(),
  sections: z.array(sectionInputSchema),
  assets: z.array(assetInputSchema),
});
