// src/client/shared/api/repositories/PaymasterRepository.ts
// Paymaster Repository for cash register operations with Zod validation

import { z } from 'zod';
import { BaseRepository } from '../BaseRepository';
import type { RequestConfig } from '../api.client';

// 1. Импортируем только ЗНАЧЕНИЯ (схемы)
import {
  paymasterRowSchema,
  createPaymasterRowSchema,
  updatePaymasterRowSchema,
  paymasterListResponseSchema,
  paymasterRowWrapperSchema,
  paymasterTotalsSchema,
  successResponseSchema,
  paymasterSuggestionsSchema,
  dateBoundariesSchema,
  paymasterPeriodReportSchema,
  PAYMASTER_TYPES, // Экспортируем как значение
} from '@shared/contracts/paymaster';

// 2. Импортируем только ТИПЫ (включая OperationType)
import type {
  PaymasterRow,
  CreatePaymasterRow,
  UpdatePaymasterRow,
  PaymasterTotals,
  SuccessResponse,
  PaymasterSuggestions,
  DateBoundaries,
  PaymasterPeriodReport,
  OperationType, // Теперь он здесь, как тип
} from '@shared/contracts/paymaster';

// 3. Реэкспортируем всё ТОЛЬКО как типы
export type {
  PaymasterRow,
  CreatePaymasterRow,
  UpdatePaymasterRow,
  PaymasterTotals,
  SuccessResponse,
  PaymasterSuggestions,
  DateBoundaries,
  PaymasterPeriodReport,
  OperationType, // Реэкспорт типа не ломает браузер
};

// 4. Реэкспортируем PAYMASTER_TYPES как значение
export { PAYMASTER_TYPES };

/**
 * Paymaster Repository
 */
export class PaymasterRepository extends BaseRepository {
  protected basePath = '/paymaster';

  /**
   * Получает все записи кассы за текущий операционный день (с кэшированием)
   */
  async fetchRows(): Promise<PaymasterRow[]> {
    const config: RequestConfig<PaymasterRow[]> = {
      schema: paymasterListResponseSchema,
    };

    return this.get<PaymasterRow[]>('/rows', config);
  }

  /**
   * Получает записи кассы за указанную дату
   */
  async fetchRowsByDate(date: string): Promise<PaymasterRow[]> {
    const config: RequestConfig<PaymasterRow[]> = {
      schema: paymasterListResponseSchema,
    };

    return this.get<PaymasterRow[]>(`/rows/date/${date}`, config);
  }

  /**
   * Получает архивированные записи (legacy endpoint)
   */
  async fetchArchivedRows(date?: string): Promise<PaymasterRow[]> {
    const config: RequestConfig<PaymasterRow[]> = {
      schema: paymasterListResponseSchema,
    };

    const query = date ? `?date=${date}` : '';
    return this.get<PaymasterRow[]>(`/rows/archived${query}`, config);
  }

  /**
   * Получает запись кассы по ID
   */
  async fetchRowById(id: string): Promise<PaymasterRow> {
    const config: RequestConfig<PaymasterRow> = {
      schema: paymasterRowSchema,
    };

    return this.get<PaymasterRow>(`/rows/${id}`, config);
  }

  /**
   * Создает новую запись кассы
   */
  async createRow(data: CreatePaymasterRow): Promise<PaymasterRow> {
    const config: RequestConfig<{ id: string }> = {
      schema: z.object({ id: z.string() }),
    };

    // Инвалидируем кэш после создания
    const result = await this.post<CreatePaymasterRow, { id: string }>('/rows', data, config);
    this.invalidateCache();
    
    // Получаем созданную запись по ID
    return this.fetchRowById(result.id);
  }

  /**
   * Обновляет запись кассы
   */
  async updateRow(data: UpdatePaymasterRow & { id: string }): Promise<PaymasterRow> {
    const config: RequestConfig<PaymasterRow> = {
      schema: paymasterRowSchema,
    };

    // Инвалидируем кэш после обновления
    const result = await this.put<UpdatePaymasterRow, PaymasterRow>(`/rows/${data.id}`, data, config);
    this.invalidateCache();
    
    return result;
  }

  /**
   * Удаляет запись кассы
   */
  async deleteRow(id: string): Promise<void> {
    // Инвалидируем кэш после удаления
    await this.delete<{ success: boolean }>(`/rows/${id}`);
    this.invalidateCache();
  }

  /**
   * Получает итоги за текущий операционный день
   */
  async fetchTotals(): Promise<PaymasterTotals> {
    const config: RequestConfig<PaymasterTotals> = {
      schema: paymasterTotalsSchema,
    };

    return this.get<PaymasterTotals>('/totals', config);
  }

  /**
   * Получает итоги за указанную дату
   */
  async fetchTotalsByDate(date: string): Promise<PaymasterTotals> {
    const config: RequestConfig<PaymasterTotals> = {
      schema: paymasterTotalsSchema,
    };

    return this.get<PaymasterTotals>(`/totals/${date}`, config);
  }

  /**
   * Получает уникальные значения полей для автокомплита (всё время)
   */
  async fetchSuggestions(): Promise<PaymasterSuggestions> {
    const config: RequestConfig<PaymasterSuggestions> = {
      schema: paymasterSuggestionsSchema,
    };

    return this.get<PaymasterSuggestions>('/suggestions', config);
  }

  /**
   * Получает границы доступных дат для навигации
   */
  async fetchDateBoundaries(): Promise<DateBoundaries> {
    const config: RequestConfig<DateBoundaries> = {
      schema: dateBoundariesSchema,
    };

    return this.get<DateBoundaries>('/date-boundaries', config);
  }

  /**
   * Получает агрегированный отчет за период операционных дней
   * @param startDate - Начальная дата периода (YYYY-MM-DD)
   * @param endDate - Конечная дата периода (YYYY-MM-DD)
   */
  async fetchPeriodReport(startDate: string, endDate: string): Promise<PaymasterPeriodReport> {
    const config: RequestConfig<PaymasterPeriodReport> = {
      schema: paymasterPeriodReportSchema,
    };

    return this.get<PaymasterPeriodReport>(
      `/period-report?startDate=${startDate}&endDate=${endDate}`,
      config
    );
  }

  /**
   * Архивирует все записи (legacy endpoint)
   */
  async archiveAllRows(): Promise<SuccessResponse> {
    const config: RequestConfig<SuccessResponse> = {
      schema: successResponseSchema,
    };

    // Инвалидируем кэш после архивации
    const result = await this.post<void, SuccessResponse>('/rows/archive', undefined, config);
    this.invalidateCache();

    return result;
  }
}

/**
 * Синглтон экземпляр PaymasterRepository
 */
export const paymasterRepository = new PaymasterRepository();
