// src/client/shared/api/repositories/TaskRepository.ts
// Task Repository with Zod validation for tasks API

import { z } from 'zod';
import { BaseRepository } from '../BaseRepository';
import type { RequestConfig } from '../api.client';
import {
  taskSchema,
  positionSchema,
  createTaskInputSchema,
  updateTaskInputSchema,
  updateTaskPositionsInputSchema,
  reorderTasksInputSchema,
  taskResponseSchema,
  tasksListResponseSchema,
} from '@shared/contracts/tasks';

// Re-export types from contracts
export type Task = typeof taskSchema._output;
export type Position = typeof positionSchema._output;
export type CreateTaskInput = typeof createTaskInputSchema._output;
export type UpdateTaskInput = typeof updateTaskInputSchema._output;
export type UpdateTaskPositionsInput = typeof updateTaskPositionsInputSchema._output;
export type ReorderTasksInput = typeof reorderTasksInputSchema._output;

/**
 * Task Repository
 */
export class TaskRepository extends BaseRepository {
  protected basePath = '/tasks';

  /**
   * Получить все задачи
   */
  async getAll(): Promise<Task[]> {
    const config: RequestConfig = {
      schema: tasksListResponseSchema,
    };

    return this.get<Task[]>(``, config);
  }

  /**
   * Получить все задачи без кэша (принудительное обновление)
   */
  async getAllFresh(): Promise<Task[]> {
    const config: RequestConfig<Task[]> = {
      schema: tasksListResponseSchema,
    };

    return this.getNoCache<Task[]>(``, config);
  }

  /**
   * Получить задачу по ID
   */
  async getById(id: string): Promise<Task> {
    const config: RequestConfig<Task> = {
      schema: taskResponseSchema,
    };

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

  /**
   * Создать новую задачу
   */
  async create(data: CreateTaskInput): Promise<Task> {
    const config: RequestConfig<Task> = {
      schema: taskResponseSchema,
    };

    return this.post<CreateTaskInput, Task>(``, data, config);
  }

  /**
   * Обновить задачу
   */
  async update(id: string, data: UpdateTaskInput): Promise<Task> {
    const config: RequestConfig<Task> = {
      schema: taskResponseSchema,
    };

    this.invalidateCache(); // Инвалидируем кэш перед обновлением

    return this.patch<UpdateTaskInput, Task>(`/${id}`, data, config);
  }

  /**
   * Удалить задачу
   */
  async deleteTask(id: string): Promise<void> {
    this.invalidateCache();
    return this.delete(`/${id}`);
  }

  /**
   * Переключить статус выполнения задачи
   */
  async toggle(id: string): Promise<Task> {
    const config: RequestConfig<Task> = {
      schema: taskResponseSchema,
    };

    return this.patch<{}, Task>(`/${id}/toggle`, {}, config);
  }

  /**
   * Обновить позиции задач (массовое обновление для сетки)
   */
  async updatePositions(data: UpdateTaskPositionsInput): Promise<boolean> {
    const config: RequestConfig<{ success: boolean }> = {
      schema: z.object({
        success: z.boolean(),
      }),
    };

    const response = await this.post<UpdateTaskPositionsInput, { success: boolean }>('/positions', data, config);
    return response.success;
  }

  /**
   * Переупорядочить задачи с поддержкой иерархии (массовое обновление order и parentId)
   */
  async reorder(data: ReorderTasksInput): Promise<boolean> {
    const config: RequestConfig<{ success: boolean }> = {
      schema: z.object({
        success: z.boolean(),
      }),
    };

    this.invalidateCache(); // Инвалидируем кэш перед переупорядочиванием

    console.log('[Reorder Payload]', JSON.stringify(data, null, 2));
    const response = await this.post<ReorderTasksInput, { success: boolean }>('/reorder', data, config);
    return response.success;
  }
}

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