import { z } from 'zod';
import { Uuid, DateOnly, PositiveDecimalString, NonNegativeDecimalString } from './common';
import { TASK_TYPE, TASK_STATUS, PACK_LEVEL } from '../enums';

export const TaskQuerySchema = z.object({
  warehouseId: Uuid.optional(),
  type: z.enum(TASK_TYPE).optional(),
  status: z.enum(TASK_STATUS).optional(),
  statuses: z.string().optional(),
  assignedToId: Uuid.optional(),
  groupKey: z.string().optional(),
  storerId: Uuid.optional(),
  zoneId: Uuid.optional(),
});
export type TaskQueryDto = z.infer<typeof TaskQuerySchema>;

/** RF: get next task for me, optionally restricted to types / zone. Server assigns atomically. */
export const NextTaskSchema = z.object({
  warehouseId: Uuid,
  types: z.array(z.enum(TASK_TYPE)).optional(),
  zoneId: Uuid.optional(),
  groupKey: z.string().optional(),
  deviceId: z.string().max(100).optional(),
});
export type NextTaskDto = z.infer<typeof NextTaskSchema>;

export const AssignTasksSchema = z.object({
  taskIds: z.array(Uuid).min(1),
  userId: Uuid.nullable(), // null = unassign
});

export const ReprioritiseTasksSchema = z.object({
  taskIds: z.array(Uuid).min(1),
  priority: z.number().int().min(1).max(9),
});

export const CancelTasksSchema = z.object({
  taskIds: z.array(Uuid).min(1),
  reason: z.string().max(500).optional(),
});

/** Confirmation payload for a task. Fields depend on task type; validated per type server-side. */
export const ConfirmTaskSchema = z.object({
  // what was scanned
  fromLocationCode: z.string().optional(),
  toLocationCode: z.string().optional(),
  lpnNumber: z.string().optional(),
  toLpnNumber: z.string().optional(),
  barcode: z.string().optional(), // sku / pack barcode scanned
  qty: NonNegativeDecimalString.optional(), // quantity done this confirmation (packLevel units); 0 allowed together with shortQty (nothing found)
  packLevel: z.enum(PACK_LEVEL).optional(),
  lotNumber: z.string().optional(),
  expiryDate: DateOnly.optional(),
  serials: z.array(z.string()).default([]),
  // exceptions
  shortQty: PositiveDecimalString.optional(), // quantity not found (short pick)
  reasonCodeId: Uuid.optional(),
  notes: z.string().max(500).optional(),
  idempotencyKey: z.string().max(100).optional(),
  deviceId: z.string().max(100).optional(),
});
export type ConfirmTaskDto = z.infer<typeof ConfirmTaskSchema>;

export const TaskExceptionSchema = z.object({
  code: z.enum(['LOCATION_EMPTY', 'DAMAGED', 'WRONG_SKU', 'LOCATION_BLOCKED', 'SKIP', 'OTHER']),
  notes: z.string().max(500).optional(),
  reasonCodeId: Uuid.optional(),
});
export type TaskExceptionDto = z.infer<typeof TaskExceptionSchema>;

export const CreateMoveTaskSchema = z.object({
  warehouseId: Uuid,
  lpnNumber: z.string().optional(),
  skuId: Uuid.optional(),
  fromLocationId: Uuid,
  toLocationId: Uuid,
  qty: PositiveDecimalString.optional(),
  priority: z.number().int().min(1).max(9).default(5),
  notes: z.string().max(500).optional(),
});
