import { create } from 'zustand';
import type {
  StatsSummary,
  FunnelConversion,
  RatingEntry,
  StatsPeriod,
} from '../types/stats';
import { statsService } from '../services/stats';

function computeDateRange(period: StatsPeriod): { dateFrom: string; dateTo: string } {
  const now = new Date();
  const dateTo = formatDate(now);

  const from = new Date(now);
  switch (period) {
    case 'week':
      from.setDate(from.getDate() - 7);
      break;
    case 'month':
      from.setMonth(from.getMonth() - 1);
      break;
    case 'quarter':
      from.setMonth(from.getMonth() - 3);
      break;
    case 'year':
      from.setFullYear(from.getFullYear() - 1);
      break;
  }

  return { dateFrom: formatDate(from), dateTo };
}

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 StatsState {
  summary: StatsSummary | null;
  funnel: FunnelConversion | null;
  rating: RatingEntry[];
  selectedPeriod: StatsPeriod;
  isLoading: boolean;
  isRefreshing: boolean;
  error: string | null;

  fetchSummary: () => Promise<void>;
  fetchFunnel: () => Promise<void>;
  fetchRating: () => Promise<void>;
  fetchAll: () => Promise<void>;
  refreshAll: () => Promise<void>;
  setSelectedPeriod: (period: StatsPeriod) => void;
  clearError: () => void;
}

export const useStatsStore = create<StatsState>((set, get) => ({
  summary: null,
  funnel: null,
  rating: [],
  selectedPeriod: 'month',
  isLoading: false,
  isRefreshing: false,
  error: null,

  fetchSummary: async () => {
    const { selectedPeriod } = get();
    const { dateFrom, dateTo } = computeDateRange(selectedPeriod);
    set({ isLoading: true, error: null });
    try {
      const summary = await statsService.getSummary({ dateFrom, dateTo });
      set({ summary, isLoading: false });
    } catch (err) {
      const message = err instanceof Error ? err.message : 'Ошибка загрузки статистики';
      set({ error: message, isLoading: false });
    }
  },

  fetchFunnel: async () => {
    const { selectedPeriod } = get();
    const { dateFrom, dateTo } = computeDateRange(selectedPeriod);
    set({ isLoading: true, error: null });
    try {
      const funnel = await statsService.getFunnelConversion({ dateFrom, dateTo });
      set({ funnel, isLoading: false });
    } catch (err) {
      const message = err instanceof Error ? err.message : 'Ошибка загрузки воронки';
      set({ error: message, isLoading: false });
    }
  },

  fetchRating: async () => {
    const { selectedPeriod } = get();
    set({ isLoading: true, error: null });
    try {
      const rating = await statsService.getRating(selectedPeriod);
      set({ rating, isLoading: false });
    } catch (err) {
      const message = err instanceof Error ? err.message : 'Ошибка загрузки рейтинга';
      set({ error: message, isLoading: false });
    }
  },

  fetchAll: async () => {
    const { selectedPeriod } = get();
    const { dateFrom, dateTo } = computeDateRange(selectedPeriod);
    set({ isLoading: true, error: null });
    try {
      const [summary, funnel] = await Promise.all([
        statsService.getSummary({ dateFrom, dateTo }),
        statsService.getFunnelConversion({ dateFrom, dateTo }),
      ]);
      set({ summary, funnel, isLoading: false });
    } catch (err) {
      const message = err instanceof Error ? err.message : 'Ошибка загрузки данных';
      set({ error: message, isLoading: false });
    }
  },

  refreshAll: async () => {
    const { selectedPeriod } = get();
    const { dateFrom, dateTo } = computeDateRange(selectedPeriod);
    set({ isRefreshing: true, error: null });
    try {
      const [summary, funnel] = await Promise.all([
        statsService.getSummary({ dateFrom, dateTo }),
        statsService.getFunnelConversion({ dateFrom, dateTo }),
      ]);
      set({ summary, funnel, isRefreshing: false });
    } catch (err) {
      const message = err instanceof Error ? err.message : 'Ошибка обновления данных';
      set({ error: message, isRefreshing: false });
    }
  },

  setSelectedPeriod: (period: StatsPeriod) => {
    set({ selectedPeriod: period });
    get().fetchAll();
  },

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