import { createContext, FC, useContext, useEffect, useState } from "react";
import { ProfitChartDataItem, ProfitTableDataItem, StatisticsService } from "../../../../../client";
import { useForm, UseFormReturnType } from "@mantine/form";
import { FormFilters } from "../../../types/FormFilters.ts";
import { getDefaultDates } from "../../../utils/dates.ts";
import { GroupStatisticsTable } from "../components/ProfitTableSegmentedControl/ProfitTableSegmentedControl.tsx";
import { defaultDealStatus } from "../../../utils/defaultFilterValues.ts";
import { dateToString } from "../../../../../types/utils.ts";

type ProfitTabContextState = {
    form: UseFormReturnType<FormFilters, (values: FormFilters) => FormFilters>;
    isChartLoading: boolean;
    isTableLoading: boolean;
    profitChartData: ProfitChartDataItem[];
    profitTableData: ProfitTableDataItem[];
};

const ProfitTabContext = createContext<ProfitTabContextState | undefined>(
    undefined,
);

const useProfitTabContextState = () => {
    const form = useForm<FormFilters>({
        mode: "controlled",
        initialValues: {
            dateRange: getDefaultDates(),
            groupTableBy: GroupStatisticsTable.BY_DATES,
            client: null,
            marketplace: null,
            dealStatus: defaultDealStatus,
            manager: null,
            expenseTag: null,
            incomeTag: null,
        },
    });
    const [isChartLoading, setIsChartLoading] = useState(false);
    const [isTableLoading, setIsTableLoading] = useState(false);
    const [profitChartData, setProfitChartData] = useState<ProfitChartDataItem[]>([]);
    const [profitTableData, setProfitTableData] = useState<ProfitTableDataItem[]>([]);

    const getChartFilters = () => {
        const dateRange = form.values.dateRange;

        return {
            dateRange: [
                dateToString(dateRange[0]),
                dateToString(dateRange[1]),
            ],
            clientId: form.values.client?.id ?? -1,
            baseMarketplaceKey: form.values.marketplace?.key ?? "all",
            dealStatusId: form.values.dealStatus?.id ?? -1,
            managerId: form.values.manager?.id ?? -1,
            expenseTagId: form.values.expenseTag?.id ?? -1,
            incomeTagId: form.values.incomeTag?.id ?? -1,
        };
    };

    const fetchChartProfitData = () => {
        setIsChartLoading(true);
        StatisticsService.getProfitChartData({
            requestBody: getChartFilters(),
        })
            .then(res => {
                setProfitChartData(res.data);
            })
            .catch(err => console.log(err))
            .finally(() => setIsChartLoading(false));
    };

    const getTableFilters = () => {
        return {
            ...getChartFilters(),
            groupTableBy: form.values.groupTableBy,
        };
    };

    const fetchTableProfitData = () => {
        setIsTableLoading(true);
        StatisticsService.getProfitTableData({
            requestBody: getTableFilters(),
        })
            .then(res => {
                setProfitTableData(res.data);
            })
            .catch(err => console.log(err))
            .finally(() => setIsTableLoading(false));
    };

    useEffect(() => {
        if (form.values.dateRange.length < 2 || form.values.dateRange[1] === null) {
            return;
        }
        fetchChartProfitData();
        fetchTableProfitData();
    }, [form.values]);

    return {
        form,
        isChartLoading,
        isTableLoading,
        profitChartData,
        profitTableData,
    };
};

type ProfitTabContextProviderProps = {
    children: React.ReactNode;
};

export const ProfitTabContextProvider: FC<ProfitTabContextProviderProps> = ({ children }) => {
    const state = useProfitTabContextState();
    return (
        <ProfitTabContext.Provider value={state}>
            {children}
        </ProfitTabContext.Provider>
    );
};

export const useProfitTabContext = () => {
    const context = useContext(ProfitTabContext);
    if (!context) {
        throw new Error(
            "useProfitTabContext must be used within a ProfitTabContextProvider",
        );
    }
    return context;
};
