import { httpClient } from './base/http-client';
import { DailyCheckbox, DailyView, Task } from '@/lib/types';
import {
  formatDateForAPI,
  parseDate,
  getToday,
  addDays,
  subtractDays,
} from '@/lib/date-utils';

// Types pour les réponses API (avec dates en string)
interface ApiCheckbox {
  id: string;
  date: string;
  text: string;
  isChecked: boolean;
  type: 'task' | 'meeting';
  order: number;
  taskId?: string;
  userId: string;
  task?: Task;
  createdAt: string;
  updatedAt: string;
}

interface ApiDailyView {
  date: string;
  yesterday: ApiCheckbox[];
  today: ApiCheckbox[];
}

interface ApiHistoryItem {
  date: string;
  checkboxes: ApiCheckbox[];
}

export interface DailyHistoryFilters {
  limit?: number;
}

export interface DailySearchFilters {
  query: string;
  limit?: number;
}

// Types conservés pour la compatibilité des hooks d'historique et de recherche
export interface ReorderCheckboxesData {
  date: Date;
  checkboxIds: string[];
}

/**
 * Client HTTP pour les données Daily (lecture seule)
 * Les mutations sont gérées par les server actions dans actions/daily.ts
 */
export class DailyClient {
  /**
   * Récupère la vue daily d'aujourd'hui (hier + aujourd'hui)
   */
  async getTodaysDailyView(): Promise<DailyView> {
    const result = await httpClient.get<ApiDailyView>('/daily');
    return this.transformDailyViewDates(result);
  }

  /**
   * Récupère la vue daily pour une date donnée
   */
  async getDailyView(date: Date): Promise<DailyView> {
    const dateStr = this.formatDateForAPI(date);
    const result = await httpClient.get<ApiDailyView>(`/daily?date=${dateStr}`);
    return this.transformDailyViewDates(result);
  }

  /**
   * Récupère l'historique des checkboxes
   */
  async getCheckboxHistory(
    filters?: DailyHistoryFilters
  ): Promise<{ date: Date; checkboxes: DailyCheckbox[] }[]> {
    const params = new URLSearchParams({ action: 'history' });

    if (filters?.limit) params.append('limit', filters.limit.toString());

    const result = await httpClient.get<ApiHistoryItem[]>(`/daily?${params}`);
    return result.map((item) => ({
      date: parseDate(item.date),
      checkboxes: item.checkboxes.map((cb: ApiCheckbox) =>
        this.transformCheckboxDates(cb)
      ),
    }));
  }

  /**
   * Recherche dans les checkboxes
   */
  async searchCheckboxes(
    filters: DailySearchFilters
  ): Promise<DailyCheckbox[]> {
    const params = new URLSearchParams({
      action: 'search',
      q: filters.query,
    });

    if (filters.limit) params.append('limit', filters.limit.toString());

    const result = await httpClient.get<ApiCheckbox[]>(`/daily?${params}`);
    return result.map((cb: ApiCheckbox) => this.transformCheckboxDates(cb));
  }

  /**
   * Formate une date pour l'API (évite les décalages timezone)
   */
  formatDateForAPI(date: Date): string {
    return formatDateForAPI(date);
  }

  /**
   * Transforme les dates string d'une checkbox en objets Date
   */
  private transformCheckboxDates(checkbox: ApiCheckbox): DailyCheckbox {
    return {
      ...checkbox,
      date: parseDate(checkbox.date),
      createdAt: parseDate(checkbox.createdAt),
      updatedAt: parseDate(checkbox.updatedAt),
      isArchived: checkbox.text.includes('[ARCHIVÉ]'),
    };
  }

  /**
   * Transforme les dates string d'une vue daily en objets Date
   */
  private transformDailyViewDates(view: ApiDailyView): DailyView {
    return {
      date: parseDate(view.date),
      yesterday: view.yesterday.map((cb: ApiCheckbox) =>
        this.transformCheckboxDates(cb)
      ),
      today: view.today.map((cb: ApiCheckbox) =>
        this.transformCheckboxDates(cb)
      ),
    };
  }

  /**
   * Récupère la vue daily d'une date relative (hier, aujourd'hui, demain)
   */
  async getDailyViewByRelativeDate(
    relative: 'yesterday' | 'today' | 'tomorrow'
  ): Promise<DailyView> {
    let date: Date;

    switch (relative) {
      case 'yesterday':
        date = subtractDays(getToday(), 1);
        break;
      case 'tomorrow':
        date = addDays(getToday(), 1);
        break;
      case 'today':
      default:
        date = getToday();
        break;
    }

    return this.getDailyView(date);
  }

  /**
   * Récupère toutes les dates qui ont des dailies
   */
  async getDailyDates(): Promise<string[]> {
    const response = await httpClient.get<{ dates: string[] }>('/daily/dates');
    return response.dates;
  }

  /**
   * Récupère toutes les dates de fin des tâches avec leurs noms
   * Retourne un objet Record<string, string[]> où chaque clé est une date (YYYY-MM-DD)
   * et la valeur est un tableau de noms de tâches
   */
  async getDeadlineDates(): Promise<Record<string, string[]>> {
    const response = await httpClient.get<{ dates: Record<string, string[]> }>(
      '/daily/deadlines'
    );
    return response.dates;
  }

  /**
   * Récupère les tâches avec deadline pour une date donnée
   */
  async getDeadlineTasksForDate(date: Date): Promise<Task[]> {
    const dateStr = this.formatDateForAPI(date);
    const response = await httpClient.get<{
      tasks: Task[];
    }>(`/daily/deadline-tasks?date=${dateStr}`);
    return response.tasks;
  }

  /**
   * Récupère les checkboxes en attente (non cochées)
   */
  async getPendingCheckboxes(options?: {
    maxDays?: number;
    excludeToday?: boolean;
    type?: 'task' | 'meeting';
    limit?: number;
  }): Promise<DailyCheckbox[]> {
    const params = new URLSearchParams();
    if (options?.maxDays) params.append('maxDays', options.maxDays.toString());
    if (options?.excludeToday !== undefined)
      params.append('excludeToday', options.excludeToday.toString());
    if (options?.type) params.append('type', options.type);
    if (options?.limit) params.append('limit', options.limit.toString());

    const queryString = params.toString();
    const result = await httpClient.get<ApiCheckbox[]>(
      `/daily/pending${queryString ? `?${queryString}` : ''}`
    );
    return result.map((cb: ApiCheckbox) => this.transformCheckboxDates(cb));
  }

  /**
   * Archive une checkbox
   */
  async archiveCheckbox(checkboxId: string): Promise<DailyCheckbox> {
    const result = await httpClient.patch<ApiCheckbox>(
      `/daily/checkboxes/${checkboxId}/archive`
    );
    return this.transformCheckboxDates(result);
  }
}

// Instance singleton du client
export const dailyClient = new DailyClient();
