'use client';

import { useState, useEffect, useCallback, useTransition } from 'react';
import { dailyClient, ReorderCheckboxesData } from '@/clients/daily-client';
import {
  DailyView,
  DailyCheckbox,
  UpdateDailyCheckboxData,
  DailyCheckboxType,
} from '@/lib/types';
import { addDays, subtractDays, getToday } from '@/lib/date-utils';
import {
  toggleCheckbox as toggleCheckboxAction,
  addTodayCheckbox as addTodayCheckboxAction,
  addYesterdayCheckbox as addYesterdayCheckboxAction,
  updateCheckbox as updateCheckboxAction,
  deleteCheckbox as deleteCheckboxAction,
  reorderCheckboxes as reorderCheckboxesAction,
} from '@/actions/daily';

interface UseDailyState {
  dailyView: DailyView | null;
  loading: boolean;
  refreshing: boolean; // Pour les refresh silencieux
  error: string | null;
  saving: boolean; // Pour indiquer les opérations en cours
  isPending: boolean; // Pour indiquer les server actions en cours
}

interface UseDailyActions {
  refreshDaily: () => Promise<void>;
  refreshDailySilent: () => Promise<void>;
  addTodayCheckbox: (
    text: string,
    type?: DailyCheckboxType,
    taskId?: string
  ) => Promise<DailyCheckbox | null>;
  addYesterdayCheckbox: (
    text: string,
    type?: DailyCheckboxType,
    taskId?: string
  ) => Promise<DailyCheckbox | null>;
  updateCheckbox: (
    checkboxId: string,
    data: UpdateDailyCheckboxData
  ) => Promise<DailyCheckbox | null>;
  deleteCheckbox: (checkboxId: string) => Promise<void>;
  toggleCheckbox: (checkboxId: string) => Promise<void>;
  toggleAllToday: () => Promise<void>;
  toggleAllYesterday: () => Promise<void>;
  reorderCheckboxes: (data: ReorderCheckboxesData) => Promise<void>;
  goToPreviousDay: () => Promise<void>;
  goToNextDay: () => Promise<void>;
  goToToday: () => Promise<void>;
  setDate: (date: Date) => Promise<void>;
}

/**
 * Hook pour la gestion d'une vue daily spécifique
 */
export function useDaily(
  initialDate?: Date,
  initialDailyView?: DailyView
): UseDailyState & UseDailyActions & { currentDate: Date } {
  const [currentDate, setCurrentDate] = useState<Date>(
    initialDate || getToday()
  );
  const [dailyView, setDailyView] = useState<DailyView | null>(
    initialDailyView || null
  );
  const [loading, setLoading] = useState(!initialDailyView); // Pas de loading si on a des données SSR
  const [refreshing, setRefreshing] = useState(false); // Pour les refresh silencieux
  const [error, setError] = useState<string | null>(null);
  const [saving, setSaving] = useState(false);
  const [isPending, startTransition] = useTransition();

  const refreshDaily = useCallback(async () => {
    try {
      setLoading(true);
      setError(null);

      const view = await dailyClient.getDailyView(currentDate);
      setDailyView(view);
    } catch (err) {
      setError(
        err instanceof Error
          ? err.message
          : 'Erreur lors du chargement du daily'
      );
      console.error('Erreur refreshDaily:', err);
    } finally {
      setLoading(false);
    }
  }, [currentDate]);

  const refreshDailySilent = useCallback(async () => {
    try {
      setRefreshing(true);
      // Refresh silencieux sans setLoading(true) pour éviter le clignotement
      const view = await dailyClient.getDailyView(currentDate);
      setDailyView(view);
    } catch (err) {
      console.error('Erreur refreshDailySilent:', err);
      // On n'affiche pas l'erreur pour ne pas perturber l'UX
    } finally {
      setRefreshing(false);
    }
  }, [currentDate]);

  const addTodayCheckbox = useCallback(
    (
      text: string,
      type?: DailyCheckboxType,
      taskId?: string
    ): Promise<DailyCheckbox | null> => {
      if (!dailyView) return Promise.resolve(null);

      return new Promise((resolve) => {
        startTransition(async () => {
          try {
            setError(null);

            const result = await addTodayCheckboxAction(
              text,
              type,
              taskId,
              currentDate
            );

            if (result.success && result.data) {
              // Mise à jour optimiste
              setDailyView((prev) =>
                prev
                  ? {
                      ...prev,
                      today: [...prev.today, result.data!].sort(
                        (a, b) => a.order - b.order
                      ),
                    }
                  : null
              );
              resolve(result.data);
            } else {
              setError(result.error || "Erreur lors de l'ajout de la checkbox");
              resolve(null);
            }
          } catch (err) {
            setError(
              err instanceof Error
                ? err.message
                : "Erreur lors de l'ajout de la checkbox"
            );
            console.error('Erreur addTodayCheckbox:', err);
            resolve(null);
          }
        });
      });
    },
    [dailyView, currentDate]
  );

  const addYesterdayCheckbox = useCallback(
    (
      text: string,
      type?: DailyCheckboxType,
      taskId?: string
    ): Promise<DailyCheckbox | null> => {
      if (!dailyView) return Promise.resolve(null);

      return new Promise((resolve) => {
        startTransition(async () => {
          try {
            setError(null);

            const result = await addYesterdayCheckboxAction(
              text,
              type,
              taskId,
              currentDate
            );

            if (result.success && result.data) {
              // Mise à jour optimiste
              setDailyView((prev) =>
                prev
                  ? {
                      ...prev,
                      yesterday: [...prev.yesterday, result.data!].sort(
                        (a, b) => a.order - b.order
                      ),
                    }
                  : null
              );
              resolve(result.data);
            } else {
              setError(result.error || "Erreur lors de l'ajout de la checkbox");
              resolve(null);
            }
          } catch (err) {
            setError(
              err instanceof Error
                ? err.message
                : "Erreur lors de l'ajout de la checkbox"
            );
            console.error('Erreur addYesterdayCheckbox:', err);
            resolve(null);
          }
        });
      });
    },
    [dailyView, currentDate]
  );

  const updateCheckbox = useCallback(
    (
      checkboxId: string,
      data: UpdateDailyCheckboxData
    ): Promise<DailyCheckbox | null> => {
      if (!dailyView) return Promise.resolve(null);

      return new Promise((resolve) => {
        startTransition(async () => {
          try {
            setError(null);

            const result = await updateCheckboxAction(checkboxId, data);

            if (result.success && result.data) {
              // Mise à jour optimiste
              setDailyView((prev) =>
                prev
                  ? {
                      ...prev,
                      yesterday: prev.yesterday.map((cb) =>
                        cb.id === checkboxId ? result.data! : cb
                      ),
                      today: prev.today.map((cb) =>
                        cb.id === checkboxId ? result.data! : cb
                      ),
                    }
                  : null
              );
              resolve(result.data);
            } else {
              setError(
                result.error || 'Erreur lors de la mise à jour de la checkbox'
              );
              resolve(null);
            }
          } catch (err) {
            setError(
              err instanceof Error
                ? err.message
                : 'Erreur lors de la mise à jour de la checkbox'
            );
            console.error('Erreur updateCheckbox:', err);
            resolve(null);
          }
        });
      });
    },
    [dailyView]
  );

  const deleteCheckbox = useCallback(
    (checkboxId: string): Promise<void> => {
      if (!dailyView) return Promise.resolve();

      return new Promise((resolve) => {
        startTransition(async () => {
          const previousDailyView = dailyView;

          // Mise à jour optimiste IMMÉDIATE - supprimer la checkbox
          setDailyView((prev) =>
            prev
              ? {
                  ...prev,
                  yesterday: prev.yesterday.filter(
                    (cb) => cb.id !== checkboxId
                  ),
                  today: prev.today.filter((cb) => cb.id !== checkboxId),
                }
              : null
          );

          try {
            const result = await deleteCheckboxAction(checkboxId);

            if (!result.success) {
              // Rollback en cas d'erreur
              setDailyView(previousDailyView);
              setError(
                result.error || 'Erreur lors de la suppression de la checkbox'
              );
            }
            resolve();
          } catch (err) {
            // Rollback en cas d'erreur
            setDailyView(previousDailyView);
            setError(
              err instanceof Error
                ? err.message
                : 'Erreur lors de la suppression de la checkbox'
            );
            console.error('Erreur deleteCheckbox:', err);
            resolve();
          }
        });
      });
    },
    [dailyView]
  );

  const toggleCheckbox = useCallback(
    (checkboxId: string): Promise<void> => {
      if (!dailyView) return Promise.resolve();

      return new Promise((resolve) => {
        // Trouver la checkbox dans yesterday ou today
        let checkbox = dailyView.yesterday.find((cb) => cb.id === checkboxId);
        if (!checkbox) {
          checkbox = dailyView.today.find((cb) => cb.id === checkboxId);
        }

        if (!checkbox) {
          resolve();
          return;
        }

        // Mise à jour optimiste IMMÉDIATE
        const newCheckedState = !checkbox.isChecked;
        const previousDailyView = dailyView;

        setDailyView((prev) =>
          prev
            ? {
                ...prev,
                yesterday: prev.yesterday.map((cb) =>
                  cb.id === checkboxId
                    ? { ...cb, isChecked: newCheckedState }
                    : cb
                ),
                today: prev.today.map((cb) =>
                  cb.id === checkboxId
                    ? { ...cb, isChecked: newCheckedState }
                    : cb
                ),
              }
            : null
        );

        // Appel serveur en arrière-plan (sans startTransition)
        toggleCheckboxAction(checkboxId)
          .then((result) => {
            if (!result.success) {
              // Rollback en cas d'erreur
              setDailyView(previousDailyView);
              setError(
                result.error || 'Erreur lors de la mise à jour de la checkbox'
              );
            }
            resolve();
          })
          .catch((err) => {
            // Rollback en cas d'erreur
            setDailyView(previousDailyView);
            setError(
              err instanceof Error
                ? err.message
                : 'Erreur lors de la mise à jour de la checkbox'
            );
            console.error('Erreur toggleCheckbox:', err);
            resolve();
          });
      });
    },
    [dailyView]
  );

  const toggleAllToday = useCallback(async (): Promise<void> => {
    if (!dailyView) return;

    const todayCheckboxes = dailyView.today;
    if (todayCheckboxes.length === 0) return;

    // Déterminer si on coche tout ou on décoche tout
    const allChecked = todayCheckboxes.every((cb) => cb.isChecked);
    const newCheckedState = !allChecked;

    const previousDailyView = dailyView;

    // Mise à jour optimiste IMMÉDIATE
    setDailyView((prev) =>
      prev
        ? {
            ...prev,
            today: prev.today.map((cb) => ({
              ...cb,
              isChecked: newCheckedState,
            })),
          }
        : null
    );

    try {
      // Appeler l'API pour chaque checkbox en parallèle
      await Promise.all(
        todayCheckboxes.map((checkbox) =>
          updateCheckboxAction(checkbox.id, { isChecked: newCheckedState })
        )
      );
    } catch (err) {
      // Rollback en cas d'erreur
      setDailyView(previousDailyView);
      setError(
        err instanceof Error
          ? err.message
          : 'Erreur lors de la mise à jour des checkboxes'
      );
      console.error('Erreur toggleAllToday:', err);
    }
  }, [dailyView]);

  const toggleAllYesterday = useCallback(async (): Promise<void> => {
    if (!dailyView) return;

    const yesterdayCheckboxes = dailyView.yesterday;
    if (yesterdayCheckboxes.length === 0) return;

    // Déterminer si on coche tout ou on décoche tout
    const allChecked = yesterdayCheckboxes.every((cb) => cb.isChecked);
    const newCheckedState = !allChecked;

    const previousDailyView = dailyView;

    // Mise à jour optimiste IMMÉDIATE
    setDailyView((prev) =>
      prev
        ? {
            ...prev,
            yesterday: prev.yesterday.map((cb) => ({
              ...cb,
              isChecked: newCheckedState,
            })),
          }
        : null
    );

    try {
      // Appeler l'API pour chaque checkbox en parallèle
      await Promise.all(
        yesterdayCheckboxes.map((checkbox) =>
          updateCheckboxAction(checkbox.id, { isChecked: newCheckedState })
        )
      );
    } catch (err) {
      // Rollback en cas d'erreur
      setDailyView(previousDailyView);
      setError(
        err instanceof Error
          ? err.message
          : 'Erreur lors de la mise à jour des checkboxes'
      );
      console.error('Erreur toggleAllYesterday:', err);
    }
  }, [dailyView]);

  const reorderCheckboxes = useCallback(
    async (data: ReorderCheckboxesData): Promise<void> => {
      try {
        setSaving(true);
        setError(null);

        // Convertir la date en string format YYYY-MM-DD pour la server action
        const dailyId = data.date.toISOString().split('T')[0];
        const result = await reorderCheckboxesAction(dailyId, data.checkboxIds);

        if (!result.success) {
          setError(result.error || 'Erreur lors du réordonnancement');
        }
      } catch (err) {
        setError(
          err instanceof Error ? err.message : 'Erreur lors du réordonnancement'
        );
        console.error('Erreur reorderCheckboxes:', err);
      } finally {
        setSaving(false);
      }
    },
    []
  );

  const goToPreviousDay = useCallback(async (): Promise<void> => {
    const previousDay = subtractDays(currentDate, 1);
    setCurrentDate(previousDay);
  }, [currentDate]);

  const goToNextDay = useCallback(async (): Promise<void> => {
    const nextDay = addDays(currentDate, 1);
    setCurrentDate(nextDay);
  }, [currentDate]);

  const goToToday = useCallback(async (): Promise<void> => {
    setCurrentDate(getToday());
  }, []);

  const setDate = useCallback(async (date: Date): Promise<void> => {
    setCurrentDate(date);
  }, []);

  // État pour savoir si c'est le premier chargement
  const [isInitialLoad, setIsInitialLoad] = useState(!initialDailyView);

  // Charger le daily quand la date change
  useEffect(() => {
    if (isInitialLoad) {
      // Premier chargement : utiliser refreshDaily normal seulement si pas de données SSR
      if (!initialDailyView) {
        refreshDaily().finally(() => setIsInitialLoad(false));
      } else {
        setIsInitialLoad(false);
      }
    } else {
      // Changements suivants : utiliser refreshDailySilent
      refreshDailySilent();
    }
  }, [refreshDaily, refreshDailySilent, isInitialLoad, initialDailyView]);

  return {
    // State
    dailyView,
    loading,
    refreshing,
    error,
    saving,
    isPending,
    currentDate,

    // Actions
    refreshDaily,
    refreshDailySilent,
    addTodayCheckbox,
    addYesterdayCheckbox,
    updateCheckbox,
    deleteCheckbox,
    toggleCheckbox,
    toggleAllToday,
    toggleAllYesterday,
    reorderCheckboxes,
    goToPreviousDay,
    goToNextDay,
    goToToday,
    setDate,
  };
}
