import { z } from "zod";
import {
  fulfillmentMethodValues,
  orderStatusValues,
  paymentMethodValues,
  paymentStatusValues,
} from "../db/schema.js";

const queryBoolean = z.preprocess((value) => {
  if (value === undefined) return undefined;
  if (typeof value === "boolean") return value;
  if (typeof value === "string") {
    if (["true", "1", "yes"].includes(value.toLowerCase())) return true;
    if (["false", "0", "no"].includes(value.toLowerCase())) return false;
  }
  return value;
}, z.boolean().optional());

const enumList = <T extends readonly [string, ...string[]]>(values: T) =>
  z.preprocess((value) => {
    if (typeof value === "string") {
      return value
        .split(",")
        .map((item) => item.trim())
        .filter(Boolean);
    }
    return value;
  }, z.array(z.enum(values)).optional());

export const orderIdParamSchema = z.object({
  id: z.coerce.number().int().positive(),
});

export const createOrderSchema = z
  .object({
    items: z
      .array(
        z.object({
          productId: z.coerce.number().int().positive(),
          quantity: z.coerce.number().int().min(1).max(20),
          lensChoice: z.enum(["none", "blue_cut", "power", "visit_store"]).default("none"),
          prescriptionUrl: z.string().trim().max(500).optional(),
        }),
      )
      .min(1)
      .max(50),
    fulfillmentMethod: z.enum(fulfillmentMethodValues),
    contactPhone: z.string().trim().min(7).max(30).optional(),
    deliveryAddress: z.string().trim().min(5).max(2000).optional(),
    paymentMethod: z.enum(paymentMethodValues).default("cash_on_delivery"),
    customerNotes: z.string().trim().max(2000).optional(),
  })
  .refine(
    (value) => value.fulfillmentMethod !== "delivery" || Boolean(value.deliveryAddress),
    "Delivery address is required for home delivery",
  );

export const customerOrderListQuerySchema = z.object({
  page: z.coerce.number().int().min(1).default(1),
  perPage: z.coerce.number().int().min(1).max(50).default(10),
  status: enumList(orderStatusValues),
  paymentStatus: enumList(paymentStatusValues),
  activeOnly: queryBoolean,
});

export const adminOrderListQuerySchema = z.object({
  q: z.string().trim().min(1).max(120).optional(),
  page: z.coerce.number().int().min(1).default(1),
  perPage: z.coerce.number().int().min(1).max(100).default(20),
  status: enumList(orderStatusValues),
  paymentStatus: enumList(paymentStatusValues),
  fulfillmentMethod: enumList(fulfillmentMethodValues),
  from: z.coerce.date().optional(),
  to: z.coerce.date().optional(),
  sort: z.enum(["newest", "oldest", "amount_desc", "amount_asc"]).default("newest"),
});

export const updateOrderSchema = z
  .object({
    status: z.enum(orderStatusValues).optional(),
    paymentStatus: z.enum(paymentStatusValues).optional(),
    managedByStaffId: z.coerce.number().int().positive().nullable().optional(),
    staffNotes: z.string().trim().max(2000).nullable().optional(),
  })
  .refine((value) => Object.keys(value).length > 0, "At least one field is required");
