import { z } from "zod";
import {
  numberFromForm,
  nonNegativeNumberFromForm,
  positiveNumberFromForm,
  intIdFromForm,
  nullableNumberFromForm,
  nullableIntIdFromForm,
  booleanFromForm,
  isoDateString,
} from "./common";

// === Categories ===
export const CreateCategorySchema = z.object({
  name: z.string().min(1, "Název je povinný").max(255),
  description: z.string().max(5000).nullish(),
  sort_order: numberFromForm.optional().default(0),
});
export const UpdateCategorySchema = z.object({
  name: z.string().min(1, "Název je povinný").max(255).optional(),
  description: z.string().max(5000).nullish(),
  sort_order: numberFromForm.optional(),
});
export type CreateCategoryInput = z.infer<typeof CreateCategorySchema>;
export type UpdateCategoryInput = z.infer<typeof UpdateCategorySchema>;

// === Suppliers ===
// Full mirror of the customers model: structured address + custom_fields
// (the dedicated contact_person/email/phone/notes columns and the free-text
// `address` blob were dropped; legacy clients sending them are silently
// stripped by z.object). Limits are DB-aligned.
export const CreateSupplierSchema = z.object({
  name: z.string().min(1, "Název je povinný").max(255),
  ico: z.string().max(255).nullish(),
  dic: z.string().max(255).nullish(),
  street: z.string().max(255).nullish(),
  city: z.string().max(255).nullish(),
  postal_code: z.string().max(20).nullish(),
  country: z.string().max(100).nullish(),
  custom_fields: z.array(z.unknown()).max(100).optional(),
  is_active: booleanFromForm.optional().default(true),
});
export const UpdateSupplierSchema = z.object({
  name: z.string().min(1, "Název je povinný").max(255).optional(),
  ico: z.string().max(255).nullish(),
  dic: z.string().max(255).nullish(),
  street: z.string().max(255).nullish(),
  city: z.string().max(255).nullish(),
  postal_code: z.string().max(20).nullish(),
  country: z.string().max(100).nullish(),
  custom_fields: z.array(z.unknown()).max(100).optional(),
  is_active: booleanFromForm.optional(),
});
export type CreateSupplierInput = z.infer<typeof CreateSupplierSchema>;
export type UpdateSupplierInput = z.infer<typeof UpdateSupplierSchema>;

// === Locations ===
export const CreateLocationSchema = z.object({
  code: z.string().min(1, "Kód je povinný").max(255),
  name: z.string().min(1, "Název je povinný").max(255),
  description: z.string().max(5000).nullish(),
  is_active: booleanFromForm.optional().default(true),
});
export const UpdateLocationSchema = z.object({
  code: z.string().min(1, "Kód je povinný").max(255).optional(),
  name: z.string().min(1, "Název je povinný").max(255).optional(),
  description: z.string().max(5000).nullish(),
  is_active: booleanFromForm.optional(),
});
export type CreateLocationInput = z.infer<typeof CreateLocationSchema>;
export type UpdateLocationInput = z.infer<typeof UpdateLocationSchema>;

// === Items ===
const UNIT_LIST = ["ks", "m", "kg", "bal", "sada", "m2", "m3", "l"] as const;
export const UnitEnum = z.enum(UNIT_LIST);
export type Unit = z.infer<typeof UnitEnum>;

export const CreateItemSchema = z.object({
  item_number: z.string().max(255).nullish(),
  name: z.string().min(1, "Název je povinný").max(255),
  description: z.string().max(5000).nullish(),
  category_id: nullableIntIdFromForm.nullish(),
  unit: UnitEnum,
  min_quantity: nullableNumberFromForm.nullish(),
  notes: z.string().max(5000).nullish(),
  is_active: booleanFromForm.optional().default(true),
});
export const UpdateItemSchema = z.object({
  item_number: z.string().max(255).nullish(),
  name: z.string().min(1, "Název je povinný").max(255).optional(),
  description: z.string().max(5000).nullish(),
  category_id: nullableIntIdFromForm.nullish(),
  unit: UnitEnum.optional(),
  min_quantity: nullableNumberFromForm.nullish(),
  notes: z.string().max(5000).nullish(),
  is_active: booleanFromForm.optional(),
});
export type CreateItemInput = z.infer<typeof CreateItemSchema>;
export type UpdateItemInput = z.infer<typeof UpdateItemSchema>;

// === Receipts ===
export const ReceiptItemSchema = z.object({
  item_id: intIdFromForm,
  quantity: positiveNumberFromForm,
  unit_price: nonNegativeNumberFromForm,
  location_id: nullableIntIdFromForm.nullish(),
  notes: z.string().max(5000).nullish(),
});

export const CreateReceiptSchema = z.object({
  supplier_id: nullableIntIdFromForm.nullish(),
  delivery_note_number: z.string().max(255).nullish(),
  delivery_note_date: isoDateString.nullish(),
  notes: z.string().max(5000).nullish(),
  items: z
    .array(ReceiptItemSchema)
    .min(1, "Příjem musí obsahovat alespoň jednu položku"),
});
export const UpdateReceiptSchema = z.object({
  supplier_id: nullableIntIdFromForm.nullish(),
  delivery_note_number: z.string().max(255).nullish(),
  delivery_note_date: isoDateString.nullish(),
  notes: z.string().max(5000).nullish(),
  items: z
    .array(ReceiptItemSchema)
    .min(1, "Příjem musí obsahovat alespoň jednu položku")
    .optional(),
});
export type CreateReceiptInput = z.infer<typeof CreateReceiptSchema>;
export type UpdateReceiptInput = z.infer<typeof UpdateReceiptSchema>;
export type ReceiptItemInput = z.infer<typeof ReceiptItemSchema>;

// === Issues ===
export const IssueItemSchema = z.object({
  item_id: intIdFromForm,
  batch_id: nullableIntIdFromForm.nullish(),
  quantity: positiveNumberFromForm,
  location_id: nullableIntIdFromForm.nullish(),
  reservation_id: nullableIntIdFromForm.nullish(),
  notes: z.string().max(5000).nullish(),
});

export const CreateIssueSchema = z.object({
  project_id: intIdFromForm,
  notes: z.string().max(5000).nullish(),
  items: z
    .array(IssueItemSchema)
    .min(1, "Výdej musí obsahovat alespoň jednu položku"),
});
export const UpdateIssueSchema = z.object({
  project_id: intIdFromForm.optional(),
  notes: z.string().max(5000).nullish(),
  items: z
    .array(IssueItemSchema)
    .min(1, "Výdej musí obsahovat alespoň jednu položku")
    .optional(),
});
export type CreateIssueInput = z.infer<typeof CreateIssueSchema>;
export type UpdateIssueInput = z.infer<typeof UpdateIssueSchema>;
export type IssueItemInput = z.infer<typeof IssueItemSchema>;

// === Reservations ===
export const CreateReservationSchema = z.object({
  item_id: intIdFromForm,
  project_id: intIdFromForm,
  quantity: positiveNumberFromForm,
  notes: z.string().max(5000).nullish(),
});
export type CreateReservationInput = z.infer<typeof CreateReservationSchema>;

// === Inventory ===
export const InventoryItemSchema = z.object({
  item_id: intIdFromForm,
  location_id: nullableIntIdFromForm.nullish(),
  actual_qty: nonNegativeNumberFromForm,
  notes: z.string().max(5000).nullish(),
});

export const CreateInventorySessionSchema = z.object({
  notes: z.string().max(5000).nullish(),
  items: z
    .array(InventoryItemSchema)
    .min(1, "Inventura musí obsahovat alespoň jednu položku"),
});
export const UpdateInventorySessionSchema = z.object({
  notes: z.string().max(5000).nullish(),
  items: z
    .array(InventoryItemSchema)
    .min(1, "Inventura musí obsahovat alespoň jednu položku")
    .optional(),
});
export type CreateInventorySessionInput = z.infer<
  typeof CreateInventorySessionSchema
>;
export type UpdateInventorySessionInput = z.infer<
  typeof UpdateInventorySessionSchema
>;
export type InventoryItemInput = z.infer<typeof InventoryItemSchema>;
