import { z } from "zod";
import { intIdFromForm, isoDateString, nullableNumberFromForm } from "./common";

const isoDate = isoDateString;

const intFromForm = intIdFromForm;

// Category is now a dynamic key (validated against plan_categories in the
// service). Keep it a non-empty string here.
const planCategoryEnum = z.string().trim().min(1, "Kategorie je povinná");

export const CreatePlanEntrySchema = z
  .object({
    user_id: intFromForm,
    date_from: isoDate,
    date_to: isoDate,
    project_id: nullableNumberFromForm.nullish(),
    category: planCategoryEnum.default("work"),
    note: z.string().max(500, "Maximálně 500 znaků"),
  })
  .refine((v) => v.date_to >= v.date_from, {
    message: "Datum do musí být stejné nebo po datumu od",
    path: ["date_to"],
  });

export const UpdatePlanEntrySchema = z
  .object({
    date_from: isoDate.optional(),
    date_to: isoDate.optional(),
    project_id: nullableNumberFromForm.nullish(),
    category: planCategoryEnum.optional(),
    note: z.string().max(500).optional(),
  })
  .refine(
    (v) =>
      v.date_from === undefined ||
      v.date_to === undefined ||
      v.date_to >= v.date_from,
    {
      message: "Datum do musí být stejné nebo po datumu od",
      path: ["date_to"],
    },
  );

export const CreatePlanOverrideSchema = z.object({
  user_id: intFromForm,
  shift_date: isoDate,
  project_id: nullableNumberFromForm.nullish(),
  category: planCategoryEnum,
  note: z.string().max(500, "Maximálně 500 znaků"),
});

export const UpdatePlanOverrideSchema = z.object({
  project_id: nullableNumberFromForm.nullish(),
  category: planCategoryEnum.optional(),
  note: z.string().max(500).optional(),
});

export const PlanRangeQuerySchema = z.object({
  user_id: intFromForm.optional(),
  date_from: isoDate,
  date_to: isoDate,
});

export const PlanGridQuerySchema = z.object({
  date_from: isoDate,
  date_to: isoDate,
  view: z.enum(["week", "month"]).default("week"),
});

export const BulkPlanEntrySchema = z
  .object({
    user_ids: z
      .array(intFromForm)
      .min(1, "Vyberte alespoň jednoho zaměstnance")
      .transform((ids) => [...new Set(ids)]),
    date_from: isoDate,
    date_to: isoDate,
    include_weekends: z
      .union([z.boolean(), z.string()])
      .transform((v) => v === true || v === "true" || v === "1")
      .default(false),
    project_id: nullableNumberFromForm.nullish(),
    category: planCategoryEnum.default("work"),
    note: z.string().max(500, "Maximálně 500 znaků").default(""),
  })
  .refine((v) => v.date_to >= v.date_from, {
    message: "Datum do musí být stejné nebo po datumu od",
    path: ["date_to"],
  });
