import React, { Dispatch, createContext, useContext, useReducer } from 'react';
import { languagesData } from './data';

type State = {
    text: string;
    visible: string[];
    expanded: string[];
    textTransform: 'normal' | 'uppercase' | 'lowercase';
};

type Action =
    | {
          type: 'set-text';
          text: string;
      }
    | {
          type: 'set-text-transform';
          textTransform: 'normal' | 'uppercase' | 'lowercase';
      }
    | {
          type: 'toggle-visibility';
          lang: string;
      }
    | {
          type: 'toggle-expand';
          lang: string;
      }
    | {
          type: 'expand-all';
      }
    | {
          type: 'collapse-all';
      }
    | {
          type: 'reset';
      };

const initialState: State = {
    text: '',
    textTransform: 'normal',
    visible: languagesData.map(lang => lang.code),
    expanded: [],
};

function reducer(state: State, action: Action): State {
    const newState = structuredClone(state);

    switch (action.type) {
        case 'set-text': {
            newState.text = action.text;

            return newState;
        }
        case 'set-text-transform': {
            newState.textTransform = action.textTransform;

            return newState;
        }
        case 'toggle-visibility': {
            if (newState.visible.includes(action.lang)) {
                newState.visible = newState.visible.filter(lang => lang !== action.lang);
            } else {
                newState.visible.push(action.lang);
            }

            return newState;
        }
        case 'toggle-expand': {
            if (newState.expanded.includes(action.lang)) {
                newState.expanded = newState.expanded.filter(lang => lang !== action.lang);
            } else {
                newState.expanded.push(action.lang);
            }

            return newState;
        }
        case 'expand-all': {
            newState.expanded = languagesData.map(lang => lang.code);

            return newState;
        }
        case 'collapse-all': {
            newState.expanded = [];

            return newState;
        }
        case 'reset': {
            return initialState;
        }
        default: {
            return state;
        }
    }
}

const stateCtx = createContext<State>(initialState);
const dispatchCtx = createContext<Dispatch<Action>>(() => {});

export function FontsExplorerProvider({ children }: { children: React.ReactNode }) {
    const [state, dispatch] = useReducer(reducer, initialState);

    return (
        <stateCtx.Provider value={state}>
            <dispatchCtx.Provider value={dispatch}>{children}</dispatchCtx.Provider>
        </stateCtx.Provider>
    );
}

export function useFontsExplorerState() {
    const state = useContext(stateCtx);
    const dispatch = useContext(dispatchCtx);

    return [state, dispatch] as const;
}
