import { useRef, useState } from "react";
import styles from '../../VisProg.module.css';
import { GetActionValue, type Action, type ActionTypes, type Plan } from "../components/Plan";
import { defaultPlan } from "../components/Plan.default";
import { TextField } from "../../../../components/TextField";

type PlanEditorDialogProps = {
  plan?: Plan;
  onSave: (plan: Plan | undefined) => void;
  description? : string;
};

/**
 * Adds an element to a React.JSX.Element that allows for the creation and editing of plans.
 * Renders a dialog in the current screen with buttons and text fields for names, actions and other configurability.
 * @param param0: Takes in a current plan, which can be undefined and a function which is called on saving with the potential plan.
 * @returns: JSX.Element
 * @example 
 * ``` 
 * // Within a Node's default JSX Element function
 * <PlanEditorDialog
 *   plan={data.plan}
 *   onSave={(plan) => {
 *      updateNodeData(props.id, {
 *          ...data,
 *          plan,
 *      });
 *    }}
 * /> 
 * ``` 
 */
export default function PlanEditorDialog({
  plan,
  onSave,
  description,
}: PlanEditorDialogProps) {
    // UseStates and references
    const dialogRef = useRef<HTMLDialogElement | null>(null);
    const [draftPlan, setDraftPlan] = useState<Plan | null>(null);
    const [newActionType, setNewActionType] = useState<ActionTypes>("speech");
    const [newActionValue, setNewActionValue] = useState("");

    //Button Actions
    const openCreate = () => {
        setDraftPlan({...structuredClone(defaultPlan), id: crypto.randomUUID()});
        dialogRef.current?.showModal();
    };

    const openCreateWithDescription = () => {
        setDraftPlan({...structuredClone(defaultPlan), id: crypto.randomUUID(), name: description!});
        setNewActionType("llm")
        setNewActionValue(description!)
        dialogRef.current?.showModal();
    }


    
    const openEdit = () => {
        if (!plan) return;
        setDraftPlan(structuredClone(plan));
        dialogRef.current?.showModal();
    };

    const close = () => {
        dialogRef.current?.close();
        setDraftPlan(null);
    };

    const buildAction = (): Action => {
        const id = crypto.randomUUID();
        switch (newActionType) {
        case "speech":
         return { id, text: newActionValue, type: "speech" };
        case "gesture":
            return { id, gesture: newActionValue, type: "gesture" };
        case "llm":
            return { id, goal: newActionValue, type: "llm" };
        }
    };

    return (<>
        {/* Create and edit buttons */}
        {!plan && (
            <button className={styles.nodeButton} onClick={description ? openCreateWithDescription : openCreate}>
            Create Plan
            </button>
        )}
        {plan && (
            <button className={styles.nodeButton} onClick={openEdit}>
            Edit Plan
            </button>
        )}

        {/* Start of dialog (plan editor) */}
        <dialog
            ref={dialogRef}
            className={styles.planDialog}
            onCancel={(e) => e.preventDefault()}
        >
        <form method="dialog" className="flex-col gap-md">
            <h3> {draftPlan?.id === plan?.id ? "Edit Plan" : "Create Plan"} </h3>

            {/* Plan name text field */}
            {draftPlan && (
                <TextField
                    value={draftPlan.name}
                    setValue={(name) =>
                    setDraftPlan({ ...draftPlan, name })}
                placeholder="Plan name"
                data-testid="name_text_field"/>
            )}

            {/* Entire "bottom" part (adder and steps) without cancel, confirm and reset */}
            {draftPlan && (<div className={styles.planEditor}>
                <div className={styles.planEditorLeft}>
                {/* Left Side (Action Adder) */}
                    <h4>Add Action</h4>
                    {(!plan && description && draftPlan.steps.length === 0) && (<div className={styles.stepSuggestion}>
                        <label> Filled in as a suggestion! </label>
                        <label> Feel free to change! </label>
                    </div>)}
                    <label>
                        Action Type <wbr />
                        {/* Type selection */}
                        <select
                            value={newActionType}
                            onChange={(e) =>
                                setNewActionType(e.target.value as ActionTypes)}>
                        <option value="speech">Speech Action</option>
                        <option value="gesture">Gesture Action</option>
                        <option value="llm">LLM Action</option>
                        </select>
                    </label>

                    {/* Action value editor */}
                    <TextField
                        value={newActionValue}
                        setValue={setNewActionValue}

                        // TODO: Can be done with a switch in case there's more types to come.
                        placeholder={
                        newActionType === "speech" ? "Speech text"
                        : newActionType === "gesture" ? "Gesture name"
                        : "LLM goal"
                        }
                    />
            
                    {/* Adding steps */}
                    <button
                        type="button"
                        disabled={!newActionValue}
                        onClick={() => {
                            if (!draftPlan) return;
                            // Add action to steps
                            const action = buildAction();
                            setDraftPlan({
                                ...draftPlan,
                                steps: [...draftPlan.steps, action],});
                  
                            // Reset current action building
                            setNewActionValue("");
                            setNewActionType("speech");
                        }}>
                    Add Step
                  </button>
                </div>
                
                {/* Right Side (Steps shown) */}
                <div className={styles.planEditorRight}>
                    <h4>Steps</h4>

                    {/* Show if there are no steps yet */}
                    {draftPlan.steps.length === 0 && (
                        <div className={styles.emptySteps}>
                        No steps yet
                        </div>
                    )}
            
                    
                    {/* Map over all steps, create a div for them that deletes them
                    if clicked on and add the index, name and type. as spans */}
                    {draftPlan.steps.map((step, index) => (
                        <div
                        key={step.id}
                        className={styles.planStep}
                        onClick={() => {
                            setDraftPlan({
                            ...draftPlan,
                            steps: draftPlan.steps.filter((s) => s.id !== step.id),});
                        }}>
                        <span className={styles.stepIndex}>{index + 1}.</span>
                        <span className={styles.stepType}>{step.type}:</span>
                        <span className={styles.stepName}>{
                        step.type == "goal" ? ""/* TODO: Add support for goals */ 
                        : GetActionValue(step)}
                        </span>
                    </div>
                  ))}
                </div>
              </div>
            )} {/* End Action Editor and steps shower */}

            {/* Buttons */}
            <div className="flex-row gap-md">
                {/* Close button */}
                <button type="button" onClick={close}>
                Cancel
                </button>

                {/* Confirm/ Create button */}
                <button
                type="button"
                disabled={!draftPlan}
                onClick={() => {
                    if (!draftPlan) return;
                    onSave(draftPlan);
                    close();
                }}>
                {draftPlan?.id === plan?.id ? "Confirm" : "Create"}
                </button>

                {/* Reset button */}
                <button
                type="button"
                disabled={!draftPlan}
                onClick={() => {
                    onSave(undefined);
                    close();
                }}>
                Reset
                </button>
          </div>
        </form>
      </dialog>
    </>
  );
}
