import { createSlice, PayloadAction, createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';
import { RootState } from './store';

interface DashboardState {
  apiKey: string;
  period: string;
  sales: number;
  costPrice: number;
  returnsCancellations: number;
  additionalServices: number;
  compensations: number;
  commission: number;
  logisticsCosts: number;
  marginProfit: number;
  stockWB: number;
  stockSeller: number;
  statistics: {
    ordered: number;
    revenue: number;
    cancelled: number;
    returned: number;
  };
  expenses: {
    tax?: number;
    logistics?: number;
    packaging?: number;
    other?: number;
  };
  data: any[];
}

const initialState: DashboardState = {
  apiKey: '',
  period: 'week',
  sales: 0,
  costPrice: 0,
  returnsCancellations: 0,
  additionalServices: 0,
  compensations: 0,
  commission: 0,
  logisticsCosts: 0,
  marginProfit: 0,
  stockWB: 0,
  stockSeller: 0,
  statistics: {
    ordered: 0,
    revenue: 0,
    cancelled: 0,
    returned: 0,
  },
  expenses: {},
  data: [],
};

// Use Axios instance with API key
const createAxiosInstance = (apiKey: string) => {
  return axios.create({
    headers: {
      Authorization: apiKey,
    },
  });
};

// Thunk to fetch dashboard data
export const fetchDashboardData = createAsyncThunk<
  Partial<DashboardState>,
  void,
  { state: RootState }
>('dashboard/fetchDashboardData', async (_, { getState, rejectWithValue }) => {
  const { apiKey } = getState().dashboard;

  if (!apiKey) {
    return rejectWithValue('Missing API key');
  }

  const dateTo = new Date();
  const dateFrom = new Date(dateTo);
  dateFrom.setMonth(dateTo.getMonth() - 3); // Последние 3 месяца

  const params = {
    dateFrom: dateFrom.toISOString(),
    dateTo: dateTo.toISOString(),
  };

  const axiosInstance = createAxiosInstance(apiKey);

  try {
    const [salesResponse, ordersResponse] = await Promise.all([
      axiosInstance.get('https://statistics-api.wildberries.ru/api/v1/supplier/sales', { params }),
      axiosInstance.get('https://statistics-api.wildberries.ru/api/v1/supplier/orders', { params }),
    ]);

    const salesData = salesResponse.data;
    const ordersData = ordersResponse.data;

    // Подсчет общей статистики
    const ordered = ordersData.length; // Все заказы, включая отмененные
    const cancelled = ordersData.filter((order: any) => order.isCancel).length; // Только отмененные
    const revenue = salesData
      .filter((sale: any) => sale.saleID.startsWith('S')) // Учитываем только продажи
      .reduce((sum: number, sale: any) => sum + sale.forPay, 0);
    const returned = salesData.filter((sale: any) => sale.saleID.startsWith('R')).length; // Возвраты

    return {
      sales: revenue,
      statistics: {
        ordered, // Общее количество заказов
        revenue, // Общее количество выручки
        cancelled, // Только отмененные заказы
        returned, // Возвраты товаров
      },
      data: [...salesData], // Передаем данные о продажах, если нужно
    };
  } catch (error) {
    console.error('Error fetching dashboard data:', error);
    return rejectWithValue('Failed to fetch data');
  }
});

// Slice
const dashboardSlice = createSlice({
  name: 'dashboard',
  initialState,
  reducers: {
    setApiKey: (state, action: PayloadAction<string>) => {
      state.apiKey = action.payload;
    },
    setPeriod: (state, action: PayloadAction<string>) => {
      state.period = action.payload;
    },
    setSales: (state, action: PayloadAction<number>) => {
      state.sales = action.payload;
    },
    setCostPrice: (state, action: PayloadAction<number>) => {
      state.costPrice = action.payload;
    },
    setReturnsCancellations: (state, action: PayloadAction<number>) => {
      state.returnsCancellations = action.payload;
    },
    setAdditionalServices: (state, action: PayloadAction<number>) => {
      state.additionalServices = action.payload;
    },
    setCompensations: (state, action: PayloadAction<number>) => {
      state.compensations = action.payload;
    },
    setCommission: (state, action: PayloadAction<number>) => {
      state.commission = action.payload;
    },
    setLogisticsCosts: (state, action: PayloadAction<number>) => {
      state.logisticsCosts = action.payload;
    },
    setMarginProfit: (state, action: PayloadAction<number>) => {
      state.marginProfit = action.payload;
    },
    setStockWB: (state, action: PayloadAction<number>) => {
      state.stockWB = action.payload;
    },
    setStockSeller: (state, action: PayloadAction<number>) => {
      state.stockSeller = action.payload;
    },
    setStatistics: (state, action: PayloadAction<DashboardState['statistics']>) => {
      state.statistics = action.payload;
    },
    setExpenses: (state, action: PayloadAction<DashboardState['expenses']>) => {
      state.expenses = action.payload;
    },
  },
  extraReducers: (builder) => {
    builder.addCase(fetchDashboardData.fulfilled, (state, action) => {
      if (action.payload) {
        state.sales = action.payload.sales || state.sales;
        state.statistics = action.payload.statistics || state.statistics;
        state.data = action.payload.data || state.data;
      }
    });
  },
});

export const {
  setApiKey,
  setPeriod,
  setSales,
  setCostPrice,
  setReturnsCancellations,
  setAdditionalServices,
  setCompensations,
  setCommission,
  setLogisticsCosts,
  setMarginProfit,
  setStockWB,
  setStockSeller,
  setStatistics,
  setExpenses,
} = dashboardSlice.actions;

export default dashboardSlice.reducer;
// Dashboard.tsx
import React, { useState, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { RootState, AppDispatch } from '../redux/store';
import { setApiKey, setPeriod, fetchDashboardData } from '../redux/dashboardSlice';
import Modal from './Modal';
import Sales from './Sales';
import CostPrice from './CostPrice';
import ReturnsCancellations from './ReturnsCancellations';
import AdditionalServices from './AdditionalServices';
import Compensations from './Compensations';
import Commission from './Commission';
import LogisticsCosts from './LogisticsCosts';
import MarginProfit from './MarginProfit';
import StockWB from './StockWB';
import StockSeller from './StockSeller';
import Statistics from './Statistics';
import ExpensesModal from './ExpensesModal';
import '../scss/Dashboard.scss';

const Dashboard: React.FC = () => {
  const dispatch = useDispatch<AppDispatch>();
  const { apiKey, period, data, statistics } = useSelector((state: RootState) => state.dashboard); // Извлекаем statistics
  const [isApiKeyModalOpen, setIsApiKeyModalOpen] = useState(false);
  const [isExpensesModalOpen, setIsExpensesModalOpen] = useState(false);
  const [localApiKey, setLocalApiKey] = useState(apiKey);

  useEffect(() => {
    if (apiKey) {
      dispatch(fetchDashboardData()); // Загружаем данные при наличии API ключа
    }
  }, [apiKey, dispatch]);

  const handleApiKeyChange = () => {
    dispatch(setApiKey(localApiKey));
    dispatch(fetchDashboardData());
    setIsApiKeyModalOpen(false);
  };

  const handlePeriodChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
    dispatch(setPeriod(event.target.value)); // Устанавливаем выбранный период
  };

  // Фильтрация данных по выбранному периоду
  const getFilteredData = (period: string, data: any[]) => {
    const dateTo = new Date();
    const dateFrom = new Date(dateTo);

    switch (period) {
      case 'week':
        dateFrom.setDate(dateTo.getDate() - 7);
        break;
      case 'month':
        dateFrom.setMonth(dateTo.getMonth() - 1);
        break;
      case 'quarter':
        dateFrom.setMonth(dateTo.getMonth() - 3);
        break;
      default:
        dateFrom.setDate(dateTo.getDate() - 7);
        break;
    }

    return data.filter((item: any) => {
      const itemDate = new Date(item.date);
      return itemDate >= dateFrom && itemDate <= dateTo;
    });
  };

  const filteredData = getFilteredData(period, data); // Получаем данные за текущий выбранный период

  return (
    <div className="dashboard">
      <div className="dashboard-header">
        <select value={period} onChange={handlePeriodChange}>
          <option value="week">Неделя</option>
          <option value="month">Месяц</option>
          <option value="quarter">Квартал</option>
        </select>
        <button onClick={() => setIsApiKeyModalOpen(true)}>Ввести API ключ</button>
      </div>
      <div className="dashboard-grid">
        <Sales data={filteredData} />
        <CostPrice data={filteredData} />
        <ReturnsCancellations data={filteredData} />
        <AdditionalServices data={filteredData} />
        <Compensations data={filteredData} />
        <Commission data={filteredData} />
        <LogisticsCosts data={filteredData} />
        <MarginProfit data={filteredData} />
        <StockWB data={filteredData} />
        <StockSeller data={filteredData} />
        {/* Передаем глобальные данные в компонент Statistics */}
        <Statistics
          ordered={statistics.ordered}
          revenue={statistics.revenue}
          cancelled={statistics.cancelled}
          returned={statistics.returned}
        />
        <button onClick={() => setIsExpensesModalOpen(true)}>Учесть расходы</button>
      </div>
      {isApiKeyModalOpen && (
        <Modal title="Введите API ключ" onClose={() => setIsApiKeyModalOpen(false)}>
          <input
            type="text"
            value={localApiKey}
            onChange={(e) => setLocalApiKey(e.target.value)}
            placeholder="API ключ"
          />
          <button onClick={handleApiKeyChange}>Сохранить</button>
        </Modal>
      )}
      {isExpensesModalOpen && <ExpensesModal onClose={() => setIsExpensesModalOpen(false)} />}
    </div>
  );
};

export default Dashboard;
// Statistics.tsx
import React from 'react';

interface StatisticsProps {
  ordered: number;
  revenue: number;
  cancelled: number;
  returned: number;
}

const Statistics: React.FC<StatisticsProps> = ({ ordered, revenue, cancelled, returned }) => (
  <div className="dashboard-item">
    <h3>Статистика</h3>
    <p>Заказано товаров: {ordered} шт.</p>
    <p>Выручка: {revenue} ₽</p>
    <p>Отменено заказов: {cancelled} шт.</p>
    <p>Возвращено товаров: {returned} шт.</p>
  </div>
);

export default Statistics;
import React from 'react';

interface SalesProps {
  data: any[];
}

const Sales: React.FC<SalesProps> = ({ data }) => {
  const totalSalesAmount = data
    .filter((item: any) => item.saleID.startsWith('S'))
    .reduce((sum: number, item: any) => sum + item.forPay, 0);
  const orderedCount = data.filter((item: any) => item.saleID.startsWith('S')).length;

  return (
    <div className="dashboard-item">
      <h3>Продажи</h3>
      <p>Количество: {orderedCount}</p>
      <p>Сумма: {totalSalesAmount} ₽</p>
    </div>
  );
};

export default Sales;
нужно чтобы в Dashboard.tsx все компоненты перерисовывались когда выбирается период, сделай код универсальным, чтобы в любой компонент приходили данные с учетом измененного периода