import {Action, SelectActionPopupWindowProps} from "../SelectActionPopupWindow";
import {atom, createStore, useAtom, useAtomValue, useSetAtom} from "jotai";
import {ComponentsMeta, getComponentMeta, getComponentMetaData} from "../ComponentsMeta";
import {offers} from "../../conditionsOrFilters/CardCreator";
import {
    ComponentRuntimeDataWithParentType,
    getDefaultRuntimeComponentDataWithParentType
} from "../components";
import {closeSelectActionsPopupWindow, UseScreenNavigationActions} from "../hooks";
import React, {useState} from "react";
import {Note} from "../cards";
import {ContentWithSidebars} from "../../ContentWithSidebars";
import {SelectedFiltersSidebar} from "../../SelectedFiltersSidebar";
import {fieldsContentWidth} from "../../TestablesPopupWindow";
import {Fields} from "../../Fields";
import {cloneDeep, set} from "lodash";
import {produce} from "immer";
import {NodesStore, OfferData, useNodesStore} from "../store";
import {generate} from "shortid";
import {withDecodedEntities} from "../../helpers";
import {
    atomsStore,
    PopupWindowState,
    SelectActionContext,
    SelectActionContextOffers,
    SelectActionPopupWindowStateAtom
} from "../atoms";
import {Tree} from "../Tree";
import {Testables} from "../testables";
import { __ } from "../../globals";
import {StateBranchNode} from "../StateBranchNode";
import {MemoryBranchNode} from "../MemoryBranchNode";
import {generateIdForType} from "../NodeHelpers";
import {Offers} from "../Offers";
import {Grove} from "../Grove";
import {GroveActions} from "../GroveActions";


const SelectedOfferAtom = atom<OfferData | Omit<OfferData, 'id'> | null>(null)
const SelectedOffersAtom = atom<ComponentRuntimeDataWithParentType[] | []>([])
atomsStore.set(SelectedOfferAtom, null)
atomsStore.set(SelectedOffersAtom, [])
const FieldsToRender = ({notes, setNotes}: {
    notes: Note[],
    setNotes: (value: (((prevState: Note[]) => Note[]) | Note[])) => void
}) => {
    const [selectedOffer, setSelectedOffer] = useAtom(SelectedOfferAtom)

    if (!selectedOffer) {
        return null;
    }
    return <Fields componentRuntimeData={selectedOffer!}
                   notes={notes}
                   setNotes={setNotes}
                   onUpdate={(componentRuntimeData, fieldId: string, value: string) => {
                       const offerToSet = produce(selectedOffer, (updatedSelectedOffer) => {
                           set(updatedSelectedOffer, `options.${fieldId}`, value);
                       });
                       setSelectedOffer(offerToSet)
                       atomsStore.set(SelectedOfferAtom, offerToSet)
                   }}/>;
}

function isEditMode(): boolean {
    const {context: {data}} = atomsStore.get(SelectActionPopupWindowStateAtom) as PopupWindowState<SelectActionContextOffers>

    // @ts-ignore
    return !!data?.offerId
}

// @ts-ignore
export const SelectOffers: Action = {
    id: 'select-offers',
    data: {
        name: 'Apply Offers',
    },
    onOpen: ({data: {offerId}}: SelectActionContextOffers, setCurrentScreenId) => {
        //  if mode is edit, then
        const modeIsEdit = isEditMode()

        if (modeIsEdit) {
            const store = useNodesStore.getState();
            const tree = new Tree(store, new Testables(store))

            //  -add the offer to the state
            const selectedOffer = cloneDeep(tree.getOffer(offerId!)!);
            //  -then change the screen to 3
            atomsStore.set(SelectedOfferAtom, {
                ...selectedOffer,
                parentType: 'offers',
            })
            atomsStore.set(SelectedOffersAtom, [selectedOffer])
            setCurrentScreenId(3);
        }
    },
    reset: () => {
        atomsStore.set(SelectedOfferAtom, null)
        atomsStore.set(SelectedOffersAtom, [])
    },
    // @ts-ignore
    screens: ({context: {targetBranchId}}) => [
        {
            id: 2,
            title: 'What kind of offer do you want to add?',
            content: () => {
                const [selectedOffer, setSelectedOffer] = useAtom(SelectedOfferAtom)
                const [selectedOffers, setSelectedOffers] = useAtom(SelectedOffersAtom)

                const {to}  = UseScreenNavigationActions('select-action')

                return <div className="p-4">

                    <h3 className="text-base text-gray-600">Select your Offer</h3>
                    {ComponentsMeta.offers.map(offer=> <button key={offer.id} onClick={() => {
                        const offerToSelect = getDefaultRuntimeComponentDataWithParentType(offer);
                        setSelectedOffer(offerToSelect)
                        setSelectedOffers([offerToSelect])
                        to(3)
                    }}>
                        {withDecodedEntities(getComponentMetaData(['offers', offer.id])).name}
                    </button>)}
                </div>
            },
        },
        {
            id: 3,
            title: () => {
                const [selectedOffer] = useAtom(SelectedOfferAtom)
                return selectedOffer ? withDecodedEntities(getComponentMetaData(['offers', selectedOffer.type])).name : 'Select Offer'
            },
            content: ({width, height}) => {
                const [selectedOffer, setSelectedOffer] = useAtom(SelectedOfferAtom)
                const [selectedOffers, setSelectedOffers] = useAtom(SelectedOffersAtom)

                const [notes, setNotes] = useState<Note[]>([])

                return <ContentWithSidebars width={width!}
                                            height={height}
                                            leftSidebar={<SelectedFiltersSidebar componentRuntimeData={selectedOffers}
                                                                                 onComponentSelect={
                                                                                     (type) => {
                                                                                         const offertoSelect = selectedOffers.find(({type: t}) => t === type) || null;
                                                                                         setSelectedOffer(offertoSelect)
                                                                                     }
                                                                                 }
                                                                                 parentType={'offers'}
                                                                                 onComponentRemove={() => {}}
                                            />}
                >
                    <FieldsToRender notes={notes} setNotes={setNotes} />
                </ContentWithSidebars>;
            },
            contentWidth: () => fieldsContentWidth,
            primaryBottom: () => {
                return {
                    label: isEditMode()? __('Apply Changes') : 'Add Offer',
                    onClick: () => {
                        const {updateOffer, addOffer} = useNodesStore.getState();
                        const selectedOffer = atomsStore.get(SelectedOfferAtom) as OfferData;

                        if (isEditMode()) {
                            // commit the changes!
                            updateOffer(selectedOffer)
                        } else {
                            addOffer(selectedOffer, targetBranchId)
                        }

                        closeSelectActionsPopupWindow()
                    },
                };
            }
        },
    ],
}