"use client";
import React, { useEffect, useReducer, useRef } from "react";
import { FormButton } from "@/app/components/form/forms";

interface Props {
  updateState?: (key: string, value: any) => void;
  jumpToNext?: () => void;
  state?: { vibe_expression?: string[] };
}

const STORAGE_KEY = "vibe_expression";
const MAX_SELECTION = 3;
const VIBE_OPTIONS = [
  "Bougie",
  "Eastern",
  "Funky",
  "Psychedelic",
  "Flowy",
  "Retro",
  "Natural",
];

interface State {
  selected: string[];
  error: string | null;
}

type Action =
  | { type: "TOGGLE"; payload: string }
  | { type: "SET"; payload: string[] }
  | { type: "SET_ERROR"; payload: string | null };

const reducer = (state: State, action: Action): State => {
  switch (action.type) {
    case "TOGGLE": {
      const { payload } = action;
      const alreadySelected = state.selected.includes(payload);

      if (alreadySelected) {
        return {
          ...state,
          selected: state.selected.filter((v) => v !== payload),
          error: null,
        };
      }

      if (state.selected.length >= MAX_SELECTION) {
        return {
          ...state,
          error: `You can select up to ${MAX_SELECTION} options.`,
        };
      }

      return {
        ...state,
        selected: [...state.selected, payload],
        error: null,
      };
    }

    case "SET":
      return { ...state, selected: action.payload, error: null };

    case "SET_ERROR":
      return { ...state, error: action.payload };

    default:
      return state;
  }
};

export default function VibeExpress({
  updateState = () => {},
  jumpToNext = () => {},
  state = {},
}: Props) {
  const initialSelected = state?.vibe_expression || [];
  const [localState, dispatch] = useReducer(reducer, {
    selected: initialSelected,
    error: null,
  });

  const initialized = useRef(false);
  const updateStateRef = useRef(updateState);
  updateStateRef.current = updateState;

  useEffect(() => {
    if (initialized.current) return;
    initialized.current = true;

    const saved = localStorage.getItem(STORAGE_KEY);
    if (saved) {
      try {
        const parsed = JSON.parse(saved);
        if (Array.isArray(parsed)) {
          dispatch({ type: "SET", payload: parsed });
          updateStateRef.current("vibe_expression", parsed);
        }
      } catch (e) {
        console.error("Failed to parse saved vibe_expression:", e);
      }
    }
  }, []);

  useEffect(() => {
    updateStateRef.current("vibe_expression", localState.selected);
    localStorage.setItem(STORAGE_KEY, JSON.stringify(localState.selected));
  }, [localState.selected]);

  const toggleOption = (option: string) => {
    dispatch({ type: "TOGGLE", payload: option });
  };

  const handleSave = () => {
    if (localState.selected.length === 0) {
      dispatch({
        type: "SET_ERROR",
        payload: "Please select at least one option.",
      });
      return;
    }

    jumpToNext();
  };

  return (
    <div className="relative z-20">
      <div className="mx-auto flex w-full flex-col items-center justify-center gap-10 align-middle">
        <div className="mx-auto flex w-full flex-col items-center justify-center gap-2 text-center md:w-[50%]">
          <h2 className="font-light">
            What is the vibe you{"'"}re trying to express?
          </h2>
          <p className="text-sm font-light">Choose up to 3 options</p>
        </div>
        <div className="flex w-full flex-col">
          <div className="grid grid-cols-2 items-center justify-center gap-4 md:grid-cols-4">
            {VIBE_OPTIONS.map((option) => {
              const isSelected = localState.selected.includes(option);
              return (
                <label
                  key={option}
                  className={`cursor-pointer border bg-white py-4 text-center font-medium capitalize transition-all duration-300 ${
                    isSelected
                      ? "border-green-400 outline-1 outline-green-400"
                      : "border-gray-500 hover:border-gray-950 hover:bg-gray-200"
                  }`}
                >
                  <input
                    type="checkbox"
                    name="vibe_expression"
                    value={option}
                    checked={isSelected}
                    onChange={() => toggleOption(option)}
                    className="sr-only"
                  />
                  {option}
                </label>
              );
            })}
          </div>

          {localState.error && (
            <p className="mt-2 items-center justify-center text-center text-sm text-red-500">
              {localState.error}
            </p>
          )}
        </div>
        <div className="mt-4 w-full md:w-[50%]">
          <FormButton
            id="btn_cc_save_vibe_express"
            label="Save Vibe Express"
            type="submit"
            color="gray"
            hairline="blue"
            disabled={localState.selected.length === 0}
            onClick={handleSave}
          />
        </div>
      </div>
    </div>
  );
}
