// src/client/shared/api/repositories/BlacklistRepository.ts
// Repository for blacklist API calls with caching and error handling

import { z } from 'zod';
import { BaseRepository } from '../BaseRepository';
import type { RequestConfig } from '../api.client';
import type { BlacklistEntry, BlacklistCreateRequest, BlacklistUpdateRequest } from '@shared/contracts/blacklist';

/**
 * Blacklist Response (DTO) - синхронизировано с бэкендом
 */
export const blacklistEntrySchema = z.object({
  id: z.string(),
  name: z.string(),
  phone: z.string(),
  bookingEngineCheck: z.enum(['YES', 'NO']),
  comment: z.string().nullable(),
  isApproved: z.boolean(),
  createdBy: z.string().nullable(),
  createdAt: z.string(),
  updatedAt: z.string(),
  archivedAt: z.string().nullable(),
});

export type BlacklistEntryResponse = z.infer<typeof blacklistEntrySchema>;

/**
 * Blacklist Pending Entry Response (DTO) - для записей на согласовании
 */
export const blacklistPendingEntrySchema = z.object({
  id: z.string(),
  name: z.string(),
  phone: z.string(),
  bookingEngineCheck: z.enum(['YES', 'NO']),
  comment: z.string().nullable(),
  status: z.enum(['pending', 'approved', 'rejected', 'to_delete']),
  targetId: z.string().nullable(), // ID оригинальной записи в таблице blacklist
  createdBy: z.string().nullable(),
  creatorName: z.string().nullable(), // Имя сотрудника, создавшего запись
  reviewedBy: z.string().nullable(),
  reviewedAt: z.string().nullable(),
  rejectionReason: z.string().nullable(),
  createdAt: z.string(),
  updatedAt: z.string(),
});

export type BlacklistPendingEntryResponse = z.infer<typeof blacklistPendingEntrySchema>;

// Blacklist list response schema
export const blacklistListResponseSchema = z.array(blacklistEntrySchema);

// Blacklist pending list response schema
export const blacklistPendingListResponseSchema = z.array(blacklistPendingEntrySchema);

/**
 * Create Blacklist Request
 */
export const blacklistCreateRequestSchema = z.object({
  name: z.string().min(1, 'Полное имя обязательно'),
  phone: z.string().min(1, 'Телефон обязателен'),
  bookingEngineCheck: z.enum(['YES', 'NO'], { message: 'Проверка системы бронирования обязательна' }),
  comment: z.string().optional(),
});

export type BlacklistCreateRequestTyped = z.infer<typeof blacklistCreateRequestSchema>;

/**
 * Update Blacklist Request
 */
export const blacklistUpdateRequestSchema = z.object({
  name: z.string().min(1).optional(),
  phone: z.string().min(1).optional(),
  bookingEngineCheck: z.enum(['YES', 'NO']).optional(),
  comment: z.string().optional(),
});

export type BlacklistUpdateRequestTyped = z.infer<typeof blacklistUpdateRequestSchema>;

// Approve/Reject response schema
export const blacklistActionResponseSchema = z.object({
  success: z.boolean(),
  message: z.string(),
  count: z.number().optional(),
});

export type BlacklistActionResponse = z.infer<typeof blacklistActionResponseSchema>;

/**
 * Repository for blacklist entries with caching (30 seconds)
 */
export class BlacklistRepository extends BaseRepository {
  protected basePath = '/blacklist';

  /**
   * Get all blacklist entries
   */
  async getAll(status?: 'pending' | 'approved'): Promise<BlacklistEntryResponse[]> {
    const config: RequestConfig<BlacklistEntryResponse[]> = {
      schema: blacklistListResponseSchema,
      params: status ? { status } : undefined,
    };

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

  /**
   * Get blacklist entry by ID
   */
  async getById(id: string): Promise<BlacklistEntryResponse> {
    const config: RequestConfig<BlacklistEntryResponse> = {
      schema: blacklistEntrySchema,
    };

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

  /**
   * Create new blacklist entry
   */
  async create(data: BlacklistCreateRequest): Promise<BlacklistEntryResponse> {
    const config: RequestConfig<BlacklistEntryResponse> = {
      schema: blacklistEntrySchema,
    };

    // Invalidate cache on create
    const result = await this.post<BlacklistCreateRequestTyped, BlacklistEntryResponse>('', data, config);
    this.invalidateCache();
    return result;
  }

  /**
   * Update existing blacklist entry
   */
  async update(id: string, data: BlacklistUpdateRequest): Promise<BlacklistEntryResponse> {
    const config: RequestConfig<BlacklistEntryResponse> = {
      schema: blacklistEntrySchema,
    };

    // Invalidate cache on update
    const result = await this.put<BlacklistUpdateRequestTyped, BlacklistEntryResponse>(`/${id}`, data, config);
    this.invalidateCache();
    return result;
  }

  /**
   * Delete blacklist entry
   */
  async deleteEntry(id: string): Promise<void> {
    // Invalidate cache on delete
    await super.delete(`/${id}`);
    this.invalidateCache();
  }

  /**
   * Get pending (unapproved) entries
   */
  async getPending(): Promise<BlacklistPendingEntryResponse[]> {
    const config: RequestConfig<BlacklistPendingEntryResponse[]> = {
      schema: blacklistPendingListResponseSchema,
    };

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

  /**
   * Approve all pending entries (ADMIN only)
   */
  async approveAll(): Promise<BlacklistActionResponse> {
    const config: RequestConfig<BlacklistActionResponse> = {
      schema: blacklistActionResponseSchema,
    };

    // Invalidate cache on approve
    const result = await this.post<void, BlacklistActionResponse>('/approve', undefined, config);
    this.invalidateCache();
    return result;
  }

  /**
   * Approve single pending entry (ADMIN only)
   */
  async approveEntry(id: string): Promise<{ success: boolean }> {
    const config: RequestConfig<{ success: boolean }> = {
      schema: z.object({ success: z.boolean() }),
    };

    // Invalidate cache on approve
    const result = await this.post<void, { success: boolean }>(`/approve/${id}`, undefined, config);
    this.invalidateCache();
    return result;
  }

  /**
   * Reject single pending entry (ADMIN only)
   */
  async rejectEntry(id: string): Promise<{ success: boolean }> {
    const config: RequestConfig<{ success: boolean }> = {
      schema: z.object({ success: z.boolean() }),
    };

    // Invalidate cache on reject
    const result = await this.post<void, { success: boolean }>(`/reject/${id}`, undefined, config);
    this.invalidateCache();
    return result;
  }
}

// Export singleton instance
export const blacklistRepository = new BlacklistRepository();
