import { create } from 'zustand';
import type {
  Training,
  CreateTrainingDto,
  CancelTrainingDto,
  RescheduleTrainingDto,
} from '../types/training';
import { scheduleService } from '../services/schedule';

function formatDate(date: Date): string {
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  return `${year}-${month}-${day}`;
}

interface ScheduleState {
  trainings: Training[];
  selectedDate: string;
  isLoading: boolean;
  isRefreshing: boolean;
  error: string | null;

  selectDate: (date: string) => void;
  fetchTrainingsByDate: (date?: string) => Promise<void>;
  refreshTrainings: () => Promise<void>;
  createTraining: (dto: CreateTrainingDto) => Promise<Training>;
  cancelTraining: (id: string, dto: CancelTrainingDto) => Promise<void>;
  rescheduleTraining: (
    id: string,
    dto: RescheduleTrainingDto,
  ) => Promise<void>;
  confirmTraining: (id: string) => Promise<void>;
  completeTraining: (id: string) => Promise<void>;
  clearError: () => void;
}

export const useScheduleStore = create<ScheduleState>((set, get) => ({
  trainings: [],
  selectedDate: formatDate(new Date()),
  isLoading: false,
  isRefreshing: false,
  error: null,

  selectDate: (date: string) => {
    set({ selectedDate: date });
    get().fetchTrainingsByDate(date);
  },

  fetchTrainingsByDate: async (date?: string) => {
    const targetDate = date || get().selectedDate;
    set({ isLoading: true, error: null });
    try {
      const response = await scheduleService.getTrainingsByDate(targetDate);
      set({ trainings: response.data, isLoading: false });
    } catch (err) {
      const message =
        err instanceof Error ? err.message : 'Ошибка загрузки расписания';
      set({ error: message, isLoading: false });
    }
  },

  refreshTrainings: async () => {
    const targetDate = get().selectedDate;
    set({ isRefreshing: true, error: null });
    try {
      const response = await scheduleService.getTrainingsByDate(targetDate);
      set({ trainings: response.data, isRefreshing: false });
    } catch (err) {
      const message =
        err instanceof Error ? err.message : 'Ошибка загрузки расписания';
      set({ error: message, isRefreshing: false });
    }
  },

  createTraining: async (dto: CreateTrainingDto) => {
    set({ isLoading: true, error: null });
    try {
      const training = await scheduleService.createTraining(dto);
      const { selectedDate } = get();
      if (dto.date === selectedDate) {
        set((state) => ({
          trainings: [...state.trainings, training].sort((a, b) =>
            a.startTime.localeCompare(b.startTime),
          ),
          isLoading: false,
        }));
      } else {
        set({ isLoading: false });
      }
      return training;
    } catch (err) {
      const message =
        err instanceof Error ? err.message : 'Ошибка создания тренировки';
      set({ error: message, isLoading: false });
      throw err;
    }
  },

  cancelTraining: async (id: string, dto: CancelTrainingDto) => {
    set({ error: null });
    try {
      const updated = await scheduleService.cancelTraining(id, dto);
      set((state) => ({
        trainings: state.trainings.map((t) => (t.id === id ? updated : t)),
      }));
    } catch (err) {
      const message =
        err instanceof Error ? err.message : 'Ошибка отмены тренировки';
      set({ error: message });
      throw err;
    }
  },

  rescheduleTraining: async (id: string, dto: RescheduleTrainingDto) => {
    set({ error: null });
    try {
      const updated = await scheduleService.rescheduleTraining(id, dto);
      set((state) => ({
        trainings: state.trainings
          .map((t) => (t.id === id ? updated : t))
          .filter((t) => t.date === state.selectedDate)
          .sort((a, b) => a.startTime.localeCompare(b.startTime)),
      }));
    } catch (err) {
      const message =
        err instanceof Error ? err.message : 'Ошибка переноса тренировки';
      set({ error: message });
      throw err;
    }
  },

  confirmTraining: async (id: string) => {
    set({ error: null });
    try {
      const updated = await scheduleService.confirmTraining(id);
      set((state) => ({
        trainings: state.trainings.map((t) => (t.id === id ? updated : t)),
      }));
    } catch (err) {
      const message =
        err instanceof Error ? err.message : 'Ошибка подтверждения';
      set({ error: message });
      throw err;
    }
  },

  completeTraining: async (id: string) => {
    set({ error: null });
    try {
      const updated = await scheduleService.completeTraining(id);
      set((state) => ({
        trainings: state.trainings.map((t) => (t.id === id ? updated : t)),
      }));
    } catch (err) {
      const message =
        err instanceof Error ? err.message : 'Ошибка завершения тренировки';
      set({ error: message });
      throw err;
    }
  },

  clearError: () => {
    set({ error: null });
  },
}));
