import { z } from 'zod';
import { ReturnProcessQuestionKey } from '../models';

/**
 * Constants for product categories used in the return process.
 */
export const ProductCategory = {
  Unknown: 'unknown',
  BookCalendar: 'Buch/Kalender',
  TonDatentraeger: 'Ton-/Datenträger',
  SpielwarenPuzzle: 'Spielwaren/Puzzle',
  SonstigesNonbook: 'Sonstiges und Non-Book',
  ElektronischeGeraete: 'Andere Elektronische Geräte',
  Tolino: 'Tolino',
} as const;

export type ProductCategoryKey = keyof typeof ProductCategory;

export type ProductCategory =
  (typeof ProductCategory)[keyof typeof ProductCategory];

/**
 * Constant object for item condition answers in the return process.
 * - OVP: Original packaging/as new condition
 * - Damaged: Item is damaged or has printing errors
 */
export const ItemConditionAnswer = {
  OVP: 'Originalverpackt',
  Damaged: 'Geöffnet/Defekt',
} as const;

/**
 * Type representing valid item condition answers derived from the ItemConditionAnswer constant.
 * Used for type checking and autocompletion when handling item condition responses.
 */
export type ItemConditionAnswer =
  (typeof ItemConditionAnswer)[keyof typeof ItemConditionAnswer];

/**
 * Constant object for return reason answers in the return process.
 * - Dislike: Customer doesn't like the item or wants to withdraw purchase
 * - WrongItem: Customer received the wrong item (incorrect delivery)
 */
export const ReturnReasonAnswer = {
  Dislike: 'Gefällt nicht/Widerruf',
  WrongItem: 'Fehllieferung',
  DamagedByCustomer: 'Beschädigt durch Kunde',
  ReceivedDamaged: 'Defekt bei Erhalt',
} as const;

/**
 * Type representing valid return reason answers derived from the ReturnReasonAnswer constant.
 * Used for type checking and autocompletion when handling return reason responses.
 */
export type ReturnReasonAnswer =
  (typeof ReturnReasonAnswer)[keyof typeof ReturnReasonAnswer];

/**
 * Constant object for yes/no answers in the return process.
 * Used for boolean-type questions throughout the return process flow.
 */
export const YesNoAnswer = {
  Yes: 'Ja',
  No: 'Nein',
} as const;

/**
 * Type representing valid yes/no answers derived from the YesNoAnswer constant.
 * Used for type checking and autocompletion when handling boolean responses.
 */
export type YesNoAnswer = (typeof YesNoAnswer)[keyof typeof YesNoAnswer];

/**
 * Constant object for package incomplete answers in the return process.
 * Specifies which parts of the package are missing during a return.
 * - OVP: Original packaging/box is missing
 * - ChargingCable: Charging cable is missing
 * - QuickStartGuide: Quick start guide documentation is missing
 */
export const PackageIncompleteAnswer = {
  OVP: 'Karton / Umverpackung',
  ChargingCable: 'Ladekabel',
  QuickStartGuide: 'Quickstart-Guide',
} as const;

/**
 * Type representing valid package incomplete answers derived from the PackageIncompleteAnswer constant.
 * Used for type checking and autocompletion when handling package incomplete responses.
 */
export type PackageIncompleteAnswer =
  (typeof PackageIncompleteAnswer)[keyof typeof PackageIncompleteAnswer];

/**
 * Zod schema definitions for validating return process question answers.
 * Each schema corresponds to a specific question key from ReturnProcessQuestionKey
 * and defines the expected format and allowed values for that question's answer.
 *
 * The DeliveredItem schema requires the following fields:
 * - catalogProductNumber: Product catalog number as string
 * - contributors: Contributors/authors as string
 * - ean: EAN (ISBN) as string
 * - format: Format type as string
 * - formatDetail: Detailed format description as string
 * - volume: Volume number as string
 * - manufacturer: Manufacturer/publisher as string
 * - name: Product name as string
 *
 * Additional fields are allowed via passthrough.
 */
export const ReturnProcessQuestionSchema = {
  [ReturnProcessQuestionKey.ItemCondition]: z.enum([
    ItemConditionAnswer.OVP,
    ItemConditionAnswer.Damaged,
  ]),
  [ReturnProcessQuestionKey.ReturnReason]: z.enum([
    ReturnReasonAnswer.Dislike,
    ReturnReasonAnswer.WrongItem,
  ]),
  [ReturnProcessQuestionKey.ItemDefective]: z.enum([
    YesNoAnswer.Yes,
    YesNoAnswer.No,
  ]),
  [ReturnProcessQuestionKey.DisplayDamaged]: z.enum([
    YesNoAnswer.Yes,
    YesNoAnswer.No,
  ]),
  [ReturnProcessQuestionKey.ItemDamaged]: z.enum([
    ReturnReasonAnswer.DamagedByCustomer,
    ReturnReasonAnswer.ReceivedDamaged,
  ]),
  [ReturnProcessQuestionKey.DevicePower]: z.enum([
    YesNoAnswer.Yes,
    YesNoAnswer.No,
  ]),
  [ReturnProcessQuestionKey.PackageComplete]: z.enum([
    YesNoAnswer.Yes,
    YesNoAnswer.No,
  ]),
  [ReturnProcessQuestionKey.PackageCompleteGroup]: z.any(),
  [ReturnProcessQuestionKey.PackageIncompleteInfo]: z.any(),
  [ReturnProcessQuestionKey.PackageMissingItems]: z
    .object({
      options: z
        .array(
          z.enum([
            PackageIncompleteAnswer.OVP,
            PackageIncompleteAnswer.ChargingCable,
            PackageIncompleteAnswer.QuickStartGuide,
          ]),
        )
        .min(1),
      other: z.string().optional(),
    })
    .or(
      z.object({
        options: z
          .array(
            z.enum([
              PackageIncompleteAnswer.OVP,
              PackageIncompleteAnswer.ChargingCable,
              PackageIncompleteAnswer.QuickStartGuide,
            ]),
          )
          .optional(),
        other: z.string(),
      }),
    ),
  [ReturnProcessQuestionKey.CaseDamaged]: z.enum([
    YesNoAnswer.Yes,
    YesNoAnswer.No,
  ]),
  [ReturnProcessQuestionKey.UsbPortDamaged]: z.enum([
    YesNoAnswer.Yes,
    YesNoAnswer.No,
  ]),
  [ReturnProcessQuestionKey.DeliveredItem]: z
    .object({
      catalogProductNumber: z.string().optional(),
      contributors: z.string().optional(),
      ean: z.string(),
      format: z.string().optional(),
      formatDetail: z.string().optional(),
      volume: z.string().optional(),
      manufacturer: z.string().optional(),
      name: z.string(),
    })
    .passthrough(),
} as const;

/**
 * Type representing any valid schema from ReturnProcessQuestionSchema.
 * Used for type checking when working with question schemas dynamically.
 */
export type ReturnProcessQuestionSchema =
  (typeof ReturnProcessQuestionSchema)[keyof typeof ReturnProcessQuestionSchema];
