import { z } from "zod";

import type {
  ArticleInput,
  CandidateFactCard,
  CheckStatus,
  ConfirmedFactCard,
  ImageInput,
  OptimizedArticle,
  PublishPlatform,
  QaCheck,
  QaReport,
  QualityRuleId,
} from "./types";

export const publishPlatformSchema = z.enum([
  "official_site",
  "media_article",
  "comparison_review",
  "recommendation_list",
]) satisfies z.ZodType<PublishPlatform>;

export const checkStatusSchema = z.enum([
  "pass",
  "warn",
  "fail",
]) satisfies z.ZodType<CheckStatus>;

export const qualityRuleIdSchema = z.enum([
  "industry_alignment",
  "image_text_match",
  "voice_consistency",
  "platform_fit",
  "company_name_integrity",
  "title_quality",
  "body_quality",
  "hallucination_risk",
  "claim_consistency",
  "context_sensitive_terms",
]) satisfies z.ZodType<QualityRuleId>;

export const imageInputSchema = z.object({
  type: z.enum(["description", "link"]),
  content: z.string().trim().min(1),
}) satisfies z.ZodType<ImageInput>;

export const articleInputSchema = z.object({
  title: z.string().trim().min(1),
  body: z.string().trim().min(1),
  images: z.array(imageInputSchema).default([]),
  platform: publishPlatformSchema,
  user_instructions: z.string().trim().default(""),
}) satisfies z.ZodType<ArticleInput>;

const stringOrStringArraySchema = z.preprocess((value) => {
  if (Array.isArray(value)) {
    return value
      .map((item) => (typeof item === "string" ? item.trim() : ""))
      .filter(Boolean)
      .join("、");
  }
  return value;
}, z.string().trim());

const experienceYearsSchema = z.preprocess((value) => {
  if (typeof value !== "string") return value;
  const trimmed = value.trim();
  if (
    trimmed === "" ||
    /^(?:unknown|none|null|n\/a|not\s+specified|不详|不明确|未知|无)$/i.test(
      trimmed,
    )
  ) {
    return null;
  }
  const yearMatch = trimmed.match(/\d{1,3}/);
  return yearMatch ? Number(yearMatch[0]) : value;
}, z.number().int().nonnegative().nullable().default(null));

const factCardBaseSchema = z.object({
  company_full_name: z.string().trim(),
  company_short_names: z.array(z.string().trim().min(1)).default([]),
  brand_names: z.array(z.string().trim().min(1)).default([]),
  product_names: z.array(z.string().trim().min(1)).default([]),
  target_industry: z.string().trim(),
  target_audience: stringOrStringArraySchema,
  experience_years: experienceYearsSchema,
  core_claims: z.array(z.string().trim().min(1)).default([]),
  forbidden_claims: z.array(z.string().trim().min(1)).default([]),
  image_topics: z.array(z.string().trim().min(1)).default([]),
  uncertain_items: z.array(z.string().trim().min(1)).default([]),
});

export const candidateFactCardSchema = factCardBaseSchema
  .extend({
    is_ready_for_optimization: z.boolean().optional(),
  })
  .transform((card) => ({
    ...card,
    is_ready_for_optimization: card.uncertain_items.length === 0,
  })) satisfies z.ZodType<CandidateFactCard>;

export const confirmedFactCardSchema = factCardBaseSchema
  .extend({
    company_full_name: z.string().trim().min(1),
    uncertain_items: z.array(z.never()).length(0),
    confirmed_by_user: z.literal(true),
    is_ready_for_optimization: z.boolean().optional(),
  })
  .transform((card) => ({
    ...card,
    is_ready_for_optimization: true as const,
  })) satisfies z.ZodType<ConfirmedFactCard>;

export const imageSuggestionSchema = z.object({
  source: z.string().trim().min(1),
  suggestion: z.string().trim().min(1),
});

export const optimizedArticleSchema = z.object({
  job_id: z.string().trim().min(1).optional(),
  revision: z.number().int().positive().optional(),
  title: z.string().trim().min(1),
  summary: z.string().trim().min(1),
  body_markdown: z.string().trim().min(1),
  image_suggestions: z.array(imageSuggestionSchema).default([]),
  changed_sections: z.array(z.string().trim().min(1)).default([]),
  requires_user_confirmation: z.array(z.string().trim().min(1)).default([]),
}) satisfies z.ZodType<OptimizedArticle>;

export const qaCheckSchema = z.object({
  rule_id: qualityRuleIdSchema,
  status: checkStatusSchema,
  evidence: z.string().trim().min(1),
  reason: z.string().trim().min(1),
  suggested_fix: z.string().trim().default(""),
  target_agent: z.string().trim().min(1).nullable().default(null),
}) satisfies z.ZodType<QaCheck>;

export const qaReportSchema = z.object({
  job_id: z.string().trim().min(1).optional(),
  revision: z.number().int().positive().optional(),
  overall_status: checkStatusSchema,
  checks: z.array(qaCheckSchema).default([]),
}) satisfies z.ZodType<QaReport>;
