import { defineStore } from 'pinia'
import { nextTick } from 'vue'

import type {
  ComponentObject,
  SetPushComponentsPayload,
  ImageObject,
  PageBuilderConfig,
} from '../types'

interface PageBuilderState {
  // Core Page Builder State
  componentArrayAddMethod: string | null
  localStorageItemName: string | null
  showModalTipTap: boolean
  menuRight: boolean
  borderStyle: string | null
  borderWidth: string | null
  borderColor: string | null
  borderRadiusGlobal: string | null
  borderRadiusTopLeft: string | null
  borderRadiusTopRight: string | null
  borderRadiusBottomleft: string | null
  borderRadiusBottomRight: string | null
  elementContainsHyperlink: boolean | null
  hyperlinkAbility: boolean | null
  hyperlinkInput: string | null
  hyperlinkMessage: string | null
  hyperlinkError: string | null
  hyberlinkEnable: boolean
  openHyperlinkinkInNewTab: boolean | null
  opacity: string | null
  backgroundOpacity: string | null
  textAreaVueModel: string | null
  nextSibling: HTMLElement | null
  parentElement: HTMLElement | null
  restoredElement: string | null
  currentClasses: string[]
  fontVerticalPadding: string | null
  fontHorizontalPadding: string | null
  fontVerticalMargin: string | null
  fontHorizontalMargin: string | null
  fontStyle: string | null
  fontFamily: string | null
  fontWeight: string | null
  fontBase: string | null
  fontDesktop: string | null
  fontTablet: string | null
  fontMobile: string | null
  backgroundColor: string | null
  textColor: string | null
  element: (HTMLElement & { src?: string }) | null
  component: ComponentObject | null
  components: ComponentObject[]
  basePrimaryImage: string | null
  configPageBuilder: PageBuilderConfig | null

  // Media Library State
  currentImage: ImageObject
  currentPreviewImage: string | null

  // User State
  isSaving: boolean
}

export const usePageBuilderStateStore = defineStore('pageBuilderState', {
  state: (): PageBuilderState => ({
    // Core Page Builder State
    componentArrayAddMethod: null,
    localStorageItemName: null,
    showModalTipTap: false,
    menuRight: true,
    borderStyle: null,
    borderWidth: null,
    borderColor: null,
    borderRadiusGlobal: null,
    borderRadiusTopLeft: null,
    borderRadiusTopRight: null,
    borderRadiusBottomleft: null,
    borderRadiusBottomRight: null,
    elementContainsHyperlink: null,
    hyperlinkAbility: null,
    hyperlinkInput: null,
    hyperlinkMessage: null,
    hyperlinkError: null,
    hyberlinkEnable: false,
    openHyperlinkinkInNewTab: null,
    opacity: null,
    backgroundOpacity: null,
    textAreaVueModel: null,
    nextSibling: null,
    parentElement: null,
    restoredElement: null,
    currentClasses: [],
    fontVerticalPadding: null,
    fontHorizontalPadding: null,
    fontVerticalMargin: null,
    fontHorizontalMargin: null,
    fontStyle: null,
    fontFamily: null,
    fontWeight: null,
    fontBase: null,
    fontDesktop: null,
    fontTablet: null,
    fontMobile: null,
    backgroundColor: null,
    textColor: null,
    element: null,
    component: null,
    components: [],
    basePrimaryImage: null,
    configPageBuilder: null,

    // Media Library State
    currentImage: { src: '' },
    currentPreviewImage: null,

    // User State
    isSaving: false,
  }),
  getters: {
    // Core Page Builder Getters
    getComponentArrayAddMethod(state: PageBuilderState): string | null {
      return state.componentArrayAddMethod
    },
    getLocalStorageItemName(state: PageBuilderState): string | null {
      return state.localStorageItemName
    },
    getShowModalTipTap(state: PageBuilderState): boolean {
      return state.showModalTipTap
    },
    getMenuRight(state: PageBuilderState): boolean {
      return state.menuRight
    },
    getBorderStyle(state: PageBuilderState): string | null {
      return state.borderStyle
    },
    getBorderWidth(state: PageBuilderState): string | null {
      return state.borderWidth
    },
    getBorderColor(state: PageBuilderState): string | null {
      return state.borderColor
    },
    getBorderRadiusGlobal(state: PageBuilderState): string | null {
      return state.borderRadiusGlobal
    },
    getBorderRadiusTopLeft(state: PageBuilderState): string | null {
      return state.borderRadiusTopLeft
    },
    getBorderRadiusTopRight(state: PageBuilderState): string | null {
      return state.borderRadiusTopRight
    },
    getBorderRadiusBottomleft(state: PageBuilderState): string | null {
      return state.borderRadiusBottomleft
    },
    getBorderRadiusBottomRight(state: PageBuilderState): string | null {
      return state.borderRadiusBottomRight
    },
    getElementContainsHyperlink(state: PageBuilderState): boolean | null {
      return state.elementContainsHyperlink
    },
    getHyperlinkAbility(state: PageBuilderState): boolean | null {
      return state.hyperlinkAbility
    },
    getHyperlinkInput(state: PageBuilderState): string | null {
      return state.hyperlinkInput
    },
    getHyperlinkMessage(state: PageBuilderState): string | null {
      return state.hyperlinkMessage
    },
    getHyperlinkError(state: PageBuilderState): string | null {
      return state.hyperlinkError
    },
    getHyberlinkEnable(state: PageBuilderState): boolean {
      return state.hyberlinkEnable
    },
    getOpenHyperlinkInNewTab(state: PageBuilderState): boolean | null {
      return state.openHyperlinkinkInNewTab
    },
    getOpacity(state: PageBuilderState): string | null {
      return state.opacity
    },
    getBackgroundOpacity(state: PageBuilderState): string | null {
      return state.backgroundOpacity
    },
    getTextAreaVueModel(state: PageBuilderState): string | null {
      return state.textAreaVueModel
    },
    getNextSibling(state: PageBuilderState): HTMLElement | null {
      return state.nextSibling
    },
    getParentElement(state: PageBuilderState): HTMLElement | null {
      return state.parentElement
    },
    getRestoredElement(state: PageBuilderState): string | null {
      return state.restoredElement
    },
    getCurrentClasses(state: PageBuilderState): string[] {
      return state.currentClasses
    },
    getFontStyle(state: PageBuilderState): string | null {
      return state.fontStyle
    },
    getFontVerticalPadding(state: PageBuilderState): string | null {
      return state.fontVerticalPadding
    },
    getFontHorizontalPadding(state: PageBuilderState): string | null {
      return state.fontHorizontalPadding
    },
    getFontVerticalMargin(state: PageBuilderState): string | null {
      return state.fontVerticalMargin
    },
    getFontHorizontalMargin(state: PageBuilderState): string | null {
      return state.fontHorizontalMargin
    },
    getFontFamily(state: PageBuilderState): string | null {
      return state.fontFamily
    },
    getFontWeight(state: PageBuilderState): string | null {
      return state.fontWeight
    },
    getFontBase(state: PageBuilderState): string | null {
      return state.fontBase
    },
    getFontDesktop(state: PageBuilderState): string | null {
      return state.fontDesktop
    },
    getFontTablet(state: PageBuilderState): string | null {
      return state.fontTablet
    },
    getFontMobile(state: PageBuilderState): string | null {
      return state.fontMobile
    },
    getBackgroundColor(state: PageBuilderState): string | null {
      return state.backgroundColor
    },
    getTextColor(state: PageBuilderState): string | null {
      return state.textColor
    },
    getElement(state: PageBuilderState): HTMLElement | null {
      return state.element
    },
    getComponent(state: PageBuilderState): ComponentObject | null {
      return state.component
    },
    getComponents(state: PageBuilderState): ComponentObject[] {
      return state.components
    },
    getBasePrimaryImage(state: PageBuilderState): string | null {
      return state.basePrimaryImage
    },

    getConfigPageBuilder(state: PageBuilderState): PageBuilderConfig | null {
      return state.configPageBuilder
    },

    // Media Library Getters
    getCurrentImage(state: PageBuilderState): ImageObject {
      return state.currentImage
    },
    getCurrentPreviewImage(state: PageBuilderState): string | null {
      return state.currentPreviewImage
    },

    // User Getters
    getIsSaving: (state: PageBuilderState): boolean => state.isSaving,
  },
  actions: {
    setComponentArrayAddMethod(payload: string | null): void {
      this.componentArrayAddMethod = payload
    },
    setLocalStorageItemName(payload: string | null): void {
      this.localStorageItemName = payload
    },
    setShowModalTipTap(payload: boolean): void {
      this.showModalTipTap = payload
    },
    setMenuRight(payload: boolean): void {
      this.menuRight = payload
    },
    setBorderStyle(payload: string | null): void {
      this.borderStyle = payload
    },
    setBorderWidth(payload: string | null): void {
      this.borderWidth = payload
    },
    setBorderColor(payload: string | null): void {
      this.borderColor = payload
    },
    setBorderRadiusGlobal(payload: string | null): void {
      this.borderRadiusGlobal = payload
    },
    setBorderRadiusTopLeft(payload: string | null): void {
      this.borderRadiusTopLeft = payload
    },
    setBorderRadiusTopRight(payload: string | null): void {
      this.borderRadiusTopRight = payload
    },
    setBorderRadiusBottomleft(payload: string | null): void {
      this.borderRadiusBottomleft = payload
    },
    setBorderRadiusBottomRight(payload: string | null): void {
      this.borderRadiusBottomRight = payload
    },
    setElementContainsHyperlink(payload: boolean | null): void {
      this.elementContainsHyperlink = payload
    },
    setHyperlinkAbility(payload: boolean | null): void {
      this.hyperlinkAbility = payload
    },
    setHyperlinkInput(payload: string | null): void {
      this.hyperlinkInput = payload
    },
    setHyperlinkMessage(payload: string | null): void {
      this.hyperlinkMessage = payload
    },
    setHyperlinkError(payload: string | null): void {
      this.hyperlinkError = payload
    },
    setHyberlinkEnable(payload: boolean): void {
      this.hyberlinkEnable = payload
    },
    setOpenHyperlinkInNewTab(payload: boolean | null): void {
      this.openHyperlinkinkInNewTab = payload
    },
    setOpacity(payload: string | null): void {
      this.opacity = payload
    },
    setBackgroundOpacity(payload: string | null): void {
      this.backgroundOpacity = payload
    },
    setTextAreaVueModel(payload: string | null): void {
      this.textAreaVueModel = payload
    },
    setNextSibling(payload: HTMLElement | null): void {
      this.nextSibling = payload
    },
    setParentElement(payload: HTMLElement | null): void {
      this.parentElement = payload
    },
    setRestoredElement(payload: string | null): void {
      this.restoredElement = payload
    },
    setClass(payload: string): void {
      this.currentClasses = [...this.currentClasses, payload]
    },
    removeClass(payload: string): void {
      this.currentClasses = this.currentClasses.filter((cls) => cls !== payload)
    },
    setCurrentClasses(payload: string[] | ArrayLike<string>): void {
      this.currentClasses = Array.from(payload)
    },
    setFontVerticalPadding(payload: string | null): void {
      this.fontVerticalPadding = payload
    },
    setFontHorizontalPadding(payload: string | null): void {
      this.fontHorizontalPadding = payload
    },
    setFontVerticalMargin(payload: string | null): void {
      this.fontVerticalMargin = payload
    },
    setFontHorizontalMargin(payload: string | null): void {
      this.fontHorizontalMargin = payload
    },
    setFontStyle(payload: string | null): void {
      this.fontStyle = payload
    },
    setFontFamily(payload: string | null): void {
      this.fontFamily = payload
    },
    setFontWeight(payload: string | null): void {
      this.fontWeight = payload
    },
    setFontBase(payload: string | null): void {
      this.fontBase = payload
    },
    setFontDesktop(payload: string | null): void {
      this.fontDesktop = payload
    },
    setFontTablet(payload: string | null): void {
      this.fontTablet = payload
    },
    setFontMobile(payload: string | null): void {
      this.fontMobile = payload
    },
    setBackgroundColor(payload: string | null): void {
      this.backgroundColor = payload
    },
    setTextColor(payload: string | null): void {
      this.textColor = payload
    },
    setElement(payload: HTMLElement | null): void {
      // Force reactivity by setting to null first, then the actual value
      this.element = null
      nextTick(() => {
        this.element = payload
      })
    },
    setComponent(payload: ComponentObject | null): void {
      if (!payload) {
        this.element = null
        this.component = null
        return
      }
      // Force reactivity by setting to null first, then the actual value
      this.component = null
      nextTick(() => {
        this.component = payload
      })
    },

    setComponents(payload: ComponentObject[] | null): void {
      // Force reactivity by setting to empty array first, then the actual value
      this.components = []
      nextTick(() => {
        this.components = payload || []
      })
    },
    setPushComponents(payload: SetPushComponentsPayload): void {
      const method = payload.componentArrayAddMethod ?? 'push'
      if (method === 'push') {
        this.components.push(payload.component)
      } else if (method === 'unshift') {
        this.components.unshift(payload.component)
      }
    },

    setBasePrimaryImage(payload: string | null): void {
      if (this.element) {
        this.element.src = payload ?? undefined
      }

      this.basePrimaryImage = payload
    },
    setCurrentLayoutPreview(payload: string): void {
      localStorage.setItem('preview', payload)
    },

    setConfigPageBuilder(payload: PageBuilderConfig | null): void {
      this.configPageBuilder = payload
    },

    // Media Library Actions
    setCurrentImage(payload: ImageObject): void {
      this.currentImage = payload
    },
    setCurrentPreviewImage(payload: string | null): void {
      this.currentPreviewImage = payload
    },

    // User Actions
    setIsSaving(payload: boolean): void {
      this.isSaving = payload
    },
  },
})
