import { z } from "zod"
import { CASH_DRAWER_IMPACT_MODES, PAYMENT_METHODS, PAYMENT_PROVIDERS } from "../enums.js"

const nullableTrimmedString = z.string().trim().min(1).nullable().optional()
const providerFieldValueSchema = z.union([z.string(), z.number(), z.boolean(), z.null()])
const standardCashDrawerImpactModeSchema = z.enum(CASH_DRAWER_IMPACT_MODES).refine((value) => value !== "DECREASE", {
    message: "DECREASE is reserved for advanced cash drawer flows"
})

export const CreatePaymentProviderAccountSchema = z.object({
    provider: z.enum(PAYMENT_PROVIDERS),
    label: nullableTrimmedString,
    config: z.record(z.string(), providerFieldValueSchema).default({}),
    secrets: z.record(z.string(), providerFieldValueSchema).default({}),
    active: z.boolean().default(true)
})

export const UpdatePaymentProviderAccountSchema = z.object({
    provider: z.enum(PAYMENT_PROVIDERS).optional(),
    label: nullableTrimmedString,
    config: z.record(z.string(), providerFieldValueSchema).optional(),
    secrets: z.record(z.string(), providerFieldValueSchema).optional(),
    active: z.boolean().optional()
}).refine((v) => Object.keys(v).length > 0, {
    message: "At least one field is required"
})

export const CreatePaymentProviderDeviceSchema = z.object({
    accountPaymentProviderId: z.string().uuid(),
    externalId: z.string().trim().min(1),
    label: nullableTrimmedString,
    active: z.boolean().default(true)
})

export const UpdatePaymentProviderDeviceSchema = z.object({
    accountPaymentProviderId: z.string().uuid().optional(),
    externalId: z.string().trim().min(1).optional(),
    label: nullableTrimmedString,
    active: z.boolean().optional()
}).refine((v) => Object.keys(v).length > 0, {
    message: "At least one field is required"
})

export const CreateShopPaymentMethodConfigSchema = z.object({
    method: z.enum(PAYMENT_METHODS),
    enabled: z.boolean().default(true),
    displayOrder: z.number().int().min(0).default(0),
    accountPaymentProviderId: z.string().uuid().nullable().optional(),
    defaultProviderDeviceId: z.string().uuid().nullable().optional(),
    cashDrawerImpactMode: standardCashDrawerImpactModeSchema.default("NONE")
})

export const UpdateShopPaymentMethodConfigSchema = z.object({
    enabled: z.boolean().optional(),
    displayOrder: z.number().int().min(0).optional(),
    accountPaymentProviderId: z.string().uuid().nullable().optional(),
    defaultProviderDeviceId: z.string().uuid().nullable().optional(),
    cashDrawerImpactMode: standardCashDrawerImpactModeSchema.optional()
}).refine((v) => Object.keys(v).length > 0, {
    message: "At least one field is required"
})

export const CreateStationPaymentMethodConfigSchema = z.object({
    stationId: z.string().uuid(),
    shopPaymentMethodConfigId: z.string().uuid(),
    enabled: z.boolean().default(false),
    displayOrder: z.number().int().min(0).default(0),
    isDefault: z.boolean().default(false),
    providerDeviceId: z.string().uuid().nullable().optional()
})

export const UpdateStationPaymentMethodConfigSchema = z.object({
    enabled: z.boolean().optional(),
    displayOrder: z.number().int().min(0).optional(),
    isDefault: z.boolean().optional(),
    providerDeviceId: z.string().uuid().nullable().optional()
}).refine((v) => Object.keys(v).length > 0, {
    message: "At least one field is required"
})

export type CreatePaymentProviderAccountInput = z.infer<typeof CreatePaymentProviderAccountSchema>
export type UpdatePaymentProviderAccountInput = z.infer<typeof UpdatePaymentProviderAccountSchema>
export type CreatePaymentProviderDeviceInput = z.infer<typeof CreatePaymentProviderDeviceSchema>
export type UpdatePaymentProviderDeviceInput = z.infer<typeof UpdatePaymentProviderDeviceSchema>
export type CreateShopPaymentMethodConfigInput = z.infer<typeof CreateShopPaymentMethodConfigSchema>
export type UpdateShopPaymentMethodConfigInput = z.infer<typeof UpdateShopPaymentMethodConfigSchema>
export type CreateStationPaymentMethodConfigInput = z.infer<typeof CreateStationPaymentMethodConfigSchema>
export type UpdateStationPaymentMethodConfigInput = z.infer<typeof UpdateStationPaymentMethodConfigSchema>
