// src/client/shared/api/repositories/AccessRepository.ts
// Access Repository for external access management with Zod validation

import { z } from 'zod';
import { BaseRepository, type RepositoryConfig } from '../BaseRepository';
import type { RequestConfig } from '../api.client';
import {
  externalAccessSchema,
  createAccessSchema,
  updateAccessSchema,
  accessActionResponseSchema,
} from '@shared/contracts/access';

/**
 * Helper to transform empty strings and undefined to null
 */
const emptyToNull = z.union([
  z.string().optional(),
  z.literal(''),
  z.null(),
]).transform(val => val === '' || val === undefined || val === null ? null : val);

/**
 * Access Response (DTO) - синхронизировано с бэкендом
 */
export type AccessResponse = z.infer<typeof externalAccessSchema>;

// Access list response schema
export const accessListResponseSchema = z.array(externalAccessSchema);

/**
 * Create Access Request
 */
export type CreateAccessRequest = z.infer<typeof createAccessSchema>;

/**
 * Update Access Request
 */
export type UpdateAccessRequest = z.infer<typeof updateAccessSchema>;

/**
 * Success Response for mutation operations
 */
export type SuccessResponse = z.infer<typeof accessActionResponseSchema>;

/**
 * Access Repository
 */
export class AccessRepository extends BaseRepository {
  protected basePath = '/external-access';
  protected cacheTTL = 30000; // 30 seconds cache for getAll

  /**
   * Получает все внешние доступы (с кэшированием 30 сек)
   */
  async getAll(): Promise<AccessResponse[]> {
    const config: RequestConfig<AccessResponse[]> = {
      schema: accessListResponseSchema,
    };

    return this.get<AccessResponse[]>('', config);
  }

  /**
   * Получает доступ по ID (с кэшированием)
   */
  async getById(id: string): Promise<AccessResponse> {
    const config: RequestConfig<AccessResponse> = {
      schema: externalAccessSchema,
    };

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

  /**
   * Создает новую запись доступа
   */
  async create(data: CreateAccessRequest): Promise<AccessResponse> {
    const config: RequestConfig<AccessResponse> = {
      schema: externalAccessSchema,
    };

    // Инвалидируем кэш после создания
    const result = await this.post<CreateAccessRequest, AccessResponse>('', data, config);
    this.invalidateCache();
    return result;
  }

  /**
   * Обновляет запись доступа
   */
  async update(id: string, data: UpdateAccessRequest): Promise<AccessResponse> {
    const config: RequestConfig<AccessResponse> = {
      schema: externalAccessSchema,
    };

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

  /**
   * Удаляет запись доступа
   */
  async deleteEntry(id: string): Promise<SuccessResponse> {
    const config: RequestConfig<SuccessResponse> = {
      schema: accessActionResponseSchema,
    };

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

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