/**
 * Zod schemas for case mutations (create / update).
 * Shapes mirror the FastAPI Pydantic models in web/app.py:
 *   - CaseCreateRequest
 *   - CaseUpdateRequest
 *
 * Validation rules are stricter on the UI than on the backend so the user
 * gets Hebrew-localized error messages at the field level instead of a
 * 422 blob from FastAPI.
 */

import { z } from "zod";
import type { PracticeArea, AppealSubtype } from "@/lib/practice-area";

/* Appeal numbers follow the 1xxx / 8xxx / 9xxx convention from CLAUDE.md.
 * Two accepted formats, both hyphen-separated:
 *   NNNN-YY         → "1033-25"     (case sequence + 2-digit year)
 *   NNNN-MM-YY      → "1000-04-26"  (case sequence + 2-digit month + year)
 *
 * Slashes are deliberately forbidden: FastAPI path routing can't capture
 * a `/` inside a {case_number} segment even when URL-encoded as %2F, so
 * any case with a slash becomes unreachable at
 * GET /api/cases/{case_number}/details. */
const caseNumberRe = /^[1-9]\d{3}(?:-\d{2}){1,2}$/;

const hebrewPartyRe = /[\u0590-\u05FFA-Za-z]/;

const dateString = z
  .string()
  .trim()
  .refine((v) => v === "" || /^\d{4}-\d{2}-\d{2}$/.test(v), {
    message: "תאריך חייב להיות בפורמט YYYY-MM-DD",
  });

export const expectedOutcomes = [
  { value: "",                   label: "— לא נקבע —" },
  { value: "rejection",          label: "דחייה" },
  { value: "partial_acceptance", label: "קבלה חלקית" },
  { value: "full_acceptance",    label: "קבלה מלאה" },
  { value: "betterment_levy",    label: "היטל השבחה" },
] as const;

export const caseCreateSchema = z.object({
  case_number: z
    .string()
    .trim()
    .min(1, "שדה חובה")
    .regex(caseNumberRe, "פורמט: NNNN-YY או NNNN-MM-YY (למשל 1033-25 או 1000-04-26)"),
  title: z.string().trim().min(3, "כותרת קצרה מדי").max(200, "כותרת ארוכה מדי"),
  appellants: z
    .array(z.string().trim().min(1).refine((v) => hebrewPartyRe.test(v), "שם לא תקין"))
    .min(1, "חייב להיות לפחות עורר אחד"),
  respondents: z
    .array(z.string().trim().min(1).refine((v) => hebrewPartyRe.test(v), "שם לא תקין"))
    .min(1, "חייב להיות לפחות משיב אחד"),
  subject: z.string().trim().max(500),
  property_address: z.string().trim().max(200),
  permit_number: z.string().trim().max(100),
  hearing_date: dateString,
  notes: z.string().trim().max(2000),
  expected_outcome: z.enum(
    expectedOutcomes.map((o) => o.value) as [string, ...string[]],
  ),
  practice_area: z.enum([
    "appeals_committee",
    "national_insurance",
    "labor_law",
  ] as const satisfies readonly PracticeArea[]),
  appeal_subtype: z.enum([
    "building_permit",
    "betterment_levy",
    "compensation_197",
    "unknown",
  ] as const satisfies readonly AppealSubtype[]),
});

export type CaseCreateInput = z.infer<typeof caseCreateSchema>;

/* Update schema — all fields optional so the PUT can be used for a
 * single-field edit. Empty strings are tolerated (they mean "no change"
 * in the Pydantic model). */
export const caseUpdateSchema = z.object({
  title:            z.string().trim().max(200).optional(),
  subject:          z.string().trim().max(500).optional(),
  notes:            z.string().trim().max(2000).optional(),
  hearing_date:     dateString.optional(),
  decision_date:    dateString.optional(),
  expected_outcome: z
    .enum(expectedOutcomes.map((o) => o.value) as [string, ...string[]])
    .optional(),
  status:           z.string().optional(),
});

export type CaseUpdateInput = z.infer<typeof caseUpdateSchema>;
