import { create } from 'zustand';
import type { BookingRecord, BookingGroupEvent } from '../types/booking';
import { bookingService } from '../services/booking';

function todayStr(): string {
  const d = new Date();
  return `${d.getFullYear()}-${(d.getMonth() + 1).toString().padStart(2, '0')}-${d.getDate().toString().padStart(2, '0')}`;
}

interface BookingState {
  // My schedule
  records: BookingRecord[];
  selectedDate: string;
  isLoading: boolean;
  isRefreshing: boolean;
  error: string | null;

  // Group events
  groupEvents: BookingGroupEvent[];
  isLoadingGroups: boolean;

  // Detail
  selectedRecord: BookingRecord | null;
  isUpdating: boolean;

  // Actions
  setSelectedDate: (date: string) => void;
  fetchMyRecords: () => Promise<void>;
  refreshMyRecords: () => Promise<void>;
  fetchGroupEvents: (date?: string) => Promise<void>;
  fetchRecord: (id: string) => Promise<void>;
  markAttendance: (id: string, status: 'COMPLETED' | 'NO_SHOW') => Promise<void>;
  confirmRecord: (id: string) => Promise<void>;
  cancelRecord: (id: string, reason?: string) => Promise<void>;
  clearError: () => void;
}

export const useBookingStore = create<BookingState>((set, get) => ({
  records: [],
  selectedDate: todayStr(),
  isLoading: false,
  isRefreshing: false,
  error: null,

  groupEvents: [],
  isLoadingGroups: false,

  selectedRecord: null,
  isUpdating: false,

  setSelectedDate: (date: string) => {
    set({ selectedDate: date });
    void get().fetchMyRecords();
  },

  fetchMyRecords: async () => {
    set({ isLoading: true, error: null });
    try {
      const records = await bookingService.getMyRecords(get().selectedDate);
      set({ records, isLoading: false });
    } catch (err) {
      const message = err instanceof Error ? err.message : 'Ошибка загрузки записей';
      set({ error: message, isLoading: false });
    }
  },

  refreshMyRecords: async () => {
    set({ isRefreshing: true, error: null });
    try {
      const records = await bookingService.getMyRecords(get().selectedDate);
      set({ records, isRefreshing: false });
    } catch (err) {
      const message = err instanceof Error ? err.message : 'Ошибка загрузки записей';
      set({ error: message, isRefreshing: false });
    }
  },

  fetchGroupEvents: async (date?: string) => {
    set({ isLoadingGroups: true });
    try {
      const groupEvents = await bookingService.getGroupEvents({
        date: date ?? get().selectedDate,
      });
      set({ groupEvents, isLoadingGroups: false });
    } catch (err) {
      const message = err instanceof Error ? err.message : 'Ошибка загрузки';
      set({ error: message, isLoadingGroups: false });
    }
  },

  fetchRecord: async (id: string) => {
    set({ isLoading: true, error: null });
    try {
      const record = await bookingService.getRecord(id);
      set({ selectedRecord: record, isLoading: false });
    } catch (err) {
      const message = err instanceof Error ? err.message : 'Ошибка загрузки';
      set({ error: message, isLoading: false });
    }
  },

  markAttendance: async (id: string, status: 'COMPLETED' | 'NO_SHOW') => {
    set({ isUpdating: true, error: null });
    try {
      const updated = await bookingService.markAttendance(id, status);
      set((state) => ({
        selectedRecord: updated,
        isUpdating: false,
        records: state.records.map((r) => (r.id === id ? updated : r)),
      }));
    } catch (err) {
      const message = err instanceof Error ? err.message : 'Ошибка обновления';
      set({ error: message, isUpdating: false });
    }
  },

  confirmRecord: async (id: string) => {
    set({ isUpdating: true, error: null });
    try {
      const updated = await bookingService.confirmRecord(id);
      set((state) => ({
        selectedRecord: updated,
        isUpdating: false,
        records: state.records.map((r) => (r.id === id ? updated : r)),
      }));
    } catch (err) {
      const message = err instanceof Error ? err.message : 'Ошибка подтверждения';
      set({ error: message, isUpdating: false });
    }
  },

  cancelRecord: async (id: string, reason?: string) => {
    set({ isUpdating: true, error: null });
    try {
      const updated = await bookingService.cancelRecord(id, reason);
      set((state) => ({
        selectedRecord: updated,
        isUpdating: false,
        records: state.records.map((r) => (r.id === id ? updated : r)),
      }));
    } catch (err) {
      const message = err instanceof Error ? err.message : 'Ошибка отмены';
      set({ error: message, isUpdating: false });
    }
  },

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