/**
 * Zod request validation schemas for tasks routes — tasks-board-engine.
 *
 * All schemas are used by route handlers to validate request bodies and
 * query params before touching the DB.
 */
import { z } from 'zod'

// ── Priority + Source enums (must match schema CHECK constraints) ─────────────

export const prioritySchema = z.enum(['low', 'medium', 'high', 'urgent'])
export const sourceSchema = z.enum([
  'manual',
  'email',
  'telegram',
  'slack',
  'whatsapp',
  'trello',
  'asana',
  'jira',
  'monday',
  'clickup',
])

// ── Task mutations ────────────────────────────────────────────────────────────

export const createTaskSchema = z.object({
  title: z.string().min(1).max(500),
  project_id: z.string().uuid().nullable().optional(),
  status_id: z.string().uuid(),
  priority: prioritySchema.optional().default('medium'),
  assignee_id: z.string().uuid().nullable().optional(),
  reporter_id: z.string().uuid().optional(),
  due_date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).nullable().optional(),
  estimated_hours: z.number().min(0).max(9999.99).nullable().optional(),
  source: sourceSchema.optional().default('manual'),
  external_id: z.string().max(255).nullable().optional(),
  position: z.number().optional(),
  description: z.unknown().optional().nullable(),
  labels: z.array(z.string().max(100)).optional().default([]),
})

export type CreateTaskInput = z.infer<typeof createTaskSchema>

export const updateTaskSchema = z.object({
  title: z.string().min(1).max(500).optional(),
  project_id: z.string().uuid().nullable().optional(),
  status_id: z.string().uuid().optional(),
  priority: prioritySchema.optional(),
  assignee_id: z.string().uuid().nullable().optional(),
  due_date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).nullable().optional(),
  estimated_hours: z.number().min(0).max(9999.99).nullable().optional(),
  position: z.number().optional(),
  description: z.unknown().optional().nullable(),
  labels: z.array(z.string().max(100)).optional(),
  // task-dependencies: OWNER/ADMIN may force a status move past an unsatisfied blocker.
  override: z.boolean().optional(),
})

export type UpdateTaskInput = z.infer<typeof updateTaskSchema>

export const bulkUpdateSchema = z.object({
  taskIds: z.array(z.string().uuid()).min(1).max(200),
  statusId: z.string().uuid(),
})

export type BulkUpdateInput = z.infer<typeof bulkUpdateSchema>

// ── Task query filters ────────────────────────────────────────────────────────

export const taskFiltersSchema = z.object({
  project: z.string().uuid().optional(),
  status: z.string().optional(),        // comma-separated UUIDs
  priority: z.string().optional(),      // comma-separated values
  assignee: z.string().uuid().optional(),
  source: z.string().optional(),        // comma-separated
  due_from: z.string().optional(),
  due_to: z.string().optional(),
  labels: z.string().optional(),        // comma-separated
  q: z.string().max(200).optional(),
  cursor: z.string().optional(),
  limit: z.coerce.number().int().min(1).max(100).optional().default(50),
})

export type TaskFiltersQuery = z.infer<typeof taskFiltersSchema>

// Parse comma-separated multi-value params into arrays
export function parseMultiParam(value: string | undefined): string[] | undefined {
  if (!value) return undefined
  return value
    .split(',')
    .map((v) => v.trim())
    .filter(Boolean)
}

// ── Status mutations ──────────────────────────────────────────────────────────

export const createStatusSchema = z.object({
  name: z.string().min(1).max(100),
  color: z.string().min(1).max(100),
  project_id: z.string().uuid().nullable().optional(),
  is_terminal: z.boolean().optional().default(false),
})

export type CreateStatusInput = z.infer<typeof createStatusSchema>

export const updateStatusSchema = z.object({
  name: z.string().min(1).max(100).optional(),
  color: z.string().min(1).max(100).optional(),
  is_terminal: z.boolean().optional(),
})

export type UpdateStatusInput = z.infer<typeof updateStatusSchema>

export const deleteStatusSchema = z.object({
  reassignToStatusId: z.string().uuid(),
})

export const reorderStatusSchema = z.object({
  order: z.array(
    z.object({
      id: z.string().uuid(),
      position: z.number().int().min(0),
    }),
  ).min(1),
})

export type ReorderStatusInput = z.infer<typeof reorderStatusSchema>

// ── Status list query ─────────────────────────────────────────────────────────

export const statusListQuerySchema = z.object({
  project: z.string().uuid().optional(),
})
