// src/shared/contracts/paymaster.ts
// Contracts for paymaster feature - Zod schemas and types

import { z } from 'zod';

/**
 * Типы операций кассы
 */
export const PAYMASTER_TYPES = {
  CASH: 'нал',
  CARD: 'безнал',
  ADVANCE: 'аванс',
  EXPENSE: 'расход',
} as const;

/**
 * Тип операции кассы (union type из PAYMASTER_TYPES)
 */
export type OperationType = typeof PAYMASTER_TYPES[keyof typeof PAYMASTER_TYPES];

/**
 * Zod schema для типов операций
 * Разрешает любую строку для кастомных значений
 */
export const paymasterTypeSchema = z.string().min(1, 'Тип операции обязателен');

/**
 * Paymaster Row Response (DTO) - синхронизировано с бэкендом
 */
export const paymasterRowSchema = z.object({
  id: z.string(),
  roomNumber: z.string().nullable(),
  contractor: z.string().nullable(),
  stayDates: z.string().nullable(),
  amount: z.number(),
  type: paymasterTypeSchema,
  comment: z.string().nullable(),
  operationalDay: z.string(), // ISO date string
  createdAt: z.string(),
  updatedAt: z.string(),
});

export type PaymasterRow = z.infer<typeof paymasterRowSchema>;

/**
 * Create Paymaster Row Request
 */
export const createPaymasterRowSchema = z.object({
  roomNumber: z.string().nullable(),
  contractor: z.string().nullable(),
  stayDates: z.string().nullable(),
  amount: z.coerce.number().min(0, 'Сумма не может быть отрицательной'),
  type: paymasterTypeSchema,
  comment: z.string().nullable(),
  operationalDay: z.string().optional(), // Опционально, будет установлен на бэкенде
});

export type CreatePaymasterRow = z.infer<typeof createPaymasterRowSchema>;

/**
 * Update Paymaster Row Request
 */
export const updatePaymasterRowSchema = z.object({
  roomNumber: z.string().nullable().optional(),
  contractor: z.string().nullable().optional(),
  stayDates: z.string().nullable().optional(),
  amount: z.coerce.number().min(0).optional(),
  type: paymasterTypeSchema.optional(),
  comment: z.string().nullable().optional(),
  operationalDay: z.string().optional(),
});

export type UpdatePaymasterRow = z.infer<typeof updatePaymasterRowSchema>;

/**
 * Paymaster list response schema
 */
export const paymasterListResponseSchema = z.array(paymasterRowSchema);

/**
 * Paymaster Row Response wrapper (for create/update operations)
 */
export const paymasterRowWrapperSchema = z.object({
  row: paymasterRowSchema,
});

export type PaymasterRowWrapper = z.infer<typeof paymasterRowWrapperSchema>;

/**
 * Totals Schema
 * Строгий формат из 5 полей: { cash, card, advance, other, expense }
 * cash - Наличные
 * card - Безнал
 * advance - Аванс
 * other - Прочее (все кастомные типы)
 * expense - Расход
 */
export const paymasterTotalsSchema = z.object({
  cash: z.number(),
  card: z.number(),
  advance: z.number(),
  other: z.number(),
  expense: z.number(),
});

export type PaymasterTotals = z.infer<typeof paymasterTotalsSchema>;

/**
 * Simple success response schema for mutation operations
 */
export const successResponseSchema = z.object({
  success: z.boolean(),
  message: z.string(),
});

export type SuccessResponse = z.infer<typeof successResponseSchema>;

/**
 * Paymaster Suggestions Schema
 * Уникальные значения полей для автокомплита (всё время)
 */
export const paymasterSuggestionsSchema = z.object({
  rooms: z.array(z.string()),
  contractors: z.array(z.string()),
  types: z.array(z.string()),
});

export type PaymasterSuggestions = z.infer<typeof paymasterSuggestionsSchema>;

/**
 * Date Boundaries Schema
 * Границы доступных дат для навигации
 * minDate: самая старая запись в системе
 * maxDate: всегда ограничивается текущим операционным днем
 */
export const dateBoundariesSchema = z.object({
  minDate: z.string(), // YYYY-MM-DD format
  maxDate: z.string(), // YYYY-MM-DD format
});

export type DateBoundaries = z.infer<typeof dateBoundariesSchema>;

/**
 * Paymaster Period Report Schema
 * Ответ для агрегированного отчета за период операционных дней
 * Формат: { days: [...], grandTotals: {...} }
 */
export const paymasterDayReportSchema = z.object({
  date: z.string(), // YYYY-MM-DD format
  rows: z.array(paymasterRowSchema),
  totals: paymasterTotalsSchema,
});

export type PaymasterDayReport = z.infer<typeof paymasterDayReportSchema>;

export const paymasterPeriodReportSchema = z.object({
  days: z.array(paymasterDayReportSchema),
  grandTotals: paymasterTotalsSchema,
});

export type PaymasterPeriodReport = z.infer<typeof paymasterPeriodReportSchema>;