import { Dispatch, SetStateAction, useState } from "react";
import { GroupsCrud } from "@/hooks/cruds/useDealGroupCrud";
import { DealSchema } from "@/lib/client";
import GroupWithDealsSchema from "@/types/GroupWithDealsSchema";

type Props = {
    groupsCrud: GroupsCrud;
};

export type GroupDealsSelection = {
    isDealsSelecting: boolean;
    selectedBaseDealId: number | null;
    startSelectingWithDeal: (dealId: number) => void;
    selectedGroupId: number | null;
    startSelectingWithExistingGroup: (group: GroupWithDealsSchema) => void;
    startSelecting: () => void;
    selectedDealIds: Set<number>;
    setSelectedDealIds: Dispatch<SetStateAction<Set<number>>>;
    toggleDeal: (deal: DealSchema) => void;
    finishDealsSelecting: () => void;
    cancelDealsSelecting: () => void;
};

const useGroupDealsSelection = ({ groupsCrud }: Props): GroupDealsSelection => {
    const [selectedDealIds, setSelectedDealIds] = useState<Set<number>>(
        new Set()
    );
    const [isDealsSelecting, setIsDealsSelecting] = useState<boolean>(false);
    const [selectedBaseDealId, setSelectedBaseDealId] = useState<number | null>(
        null
    );
    const [selectedGroupId, setSelectedGroupId] = useState<number | null>(null);

    const toggleDeal = (deal: DealSchema) => {
        if (selectedBaseDealId === deal.id) return;

        if (selectedDealIds.has(deal.id)) {
            selectedDealIds.delete(deal.id);
        } else {
            if (!selectedBaseDealId && !selectedGroupId) {
                if (deal.group) return;
                setSelectedBaseDealId(deal.id);
                return;
            }
            selectedDealIds.add(deal.id);
        }
        setSelectedDealIds(new Set(selectedDealIds));
    };

    const finishDealsSelecting = () => {
        if (selectedBaseDealId) {
            groupsCrud.onCreate(
                selectedBaseDealId,
                selectedDealIds.values().toArray()
            );
            setSelectedBaseDealId(null);
        } else if (selectedGroupId) {
            groupsCrud.onUpdateDealsInGroup(
                selectedGroupId,
                selectedDealIds.values().toArray()
            );
            setSelectedGroupId(null);
        }
        setIsDealsSelecting(false);
        setSelectedDealIds(new Set());
    };

    const cancelDealsSelecting = () => {
        setSelectedDealIds(new Set());
        setSelectedBaseDealId(null);
        setSelectedGroupId(null);
        setIsDealsSelecting(false);
    };

    // For editing group
    const startSelectingWithExistingGroup = (group: GroupWithDealsSchema) => {
        setSelectedDealIds(new Set(group.items.map(item => item.id)));
        setSelectedBaseDealId(null);
        setSelectedGroupId(group.id);
        setIsDealsSelecting(true);
    };

    // For creating group on desktop
    const startSelectingWithDeal = (dealId: number) => {
        setSelectedDealIds(new Set([dealId]));
        setSelectedBaseDealId(dealId);
        setSelectedGroupId(null);
        setIsDealsSelecting(true);
    };

    // For creating group on mobile
    const startSelecting = () => {
        setSelectedDealIds(new Set());
        setSelectedBaseDealId(null);
        setSelectedGroupId(null);
        setIsDealsSelecting(true);
    };

    return {
        isDealsSelecting,
        selectedBaseDealId,
        startSelectingWithDeal,
        selectedGroupId,
        startSelectingWithExistingGroup,
        startSelecting,
        selectedDealIds,
        setSelectedDealIds,
        toggleDeal,
        finishDealsSelecting,
        cancelDealsSelecting,
    };
};

export default useGroupDealsSelection;
