import { mdiArrowLeft, mdiPencil } from '@mdi/js'
import Head from 'next/head'
import Link from 'next/link'
import { useRouter } from 'next/router'
import React, { ReactElement, useCallback, useEffect, useState } from 'react'
import axios from 'axios'
import BaseButton from '../../components/BaseButton'
import CardBox from '../../components/CardBox'
import LayoutAuthenticated from '../../layouts/Authenticated'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import { hasPermission } from '../../helpers/userPermissions'
import ElementPreview from '../../components/UiElements/ElementPreview'
import { normalizeUiElement, toElementLabel } from '../../components/UiElements/defaults'
import { UiElementItem, UiElementRow } from '../../components/UiElements/types'
import { useAppSelector } from '../../stores/hooks'

const UiElementDetailsPage = () => {
  const router = useRouter()
  const { id } = router.query
  const { currentUser } = useAppSelector((state) => state.auth)
  const hasUpdatePermission = hasPermission(currentUser, 'UPDATE_PAGE_ELEMENTS')

  const [element, setElement] = useState<UiElementItem | null>(null)
  const [isLoading, setIsLoading] = useState(false)
  const [isSaving, setIsSaving] = useState(false)
  const [errorMessage, setErrorMessage] = useState('')

  const [name, setName] = useState('')
  const [color, setColor] = useState('')
  const [backgroundColor, setBackgroundColor] = useState('')
  const [border, setBorder] = useState('')
  const [position, setPosition] = useState('')
  const [widthPercent, setWidthPercent] = useState('')
  const [heightPercent, setHeightPercent] = useState('')
  const [xPercent, setXPercent] = useState('')
  const [yPercent, setYPercent] = useState('')
  const [title, setTitle] = useState('')
  const [placeholder, setPlaceholder] = useState('')
  const [text, setText] = useState('')

  const applyElementToForm = useCallback((item: UiElementItem) => {
    setName(item.name)
    setColor(item.settings.style.color)
    setBackgroundColor(item.settings.style.backgroundColor)
    setBorder(item.settings.style.border)
    setPosition(item.settings.layout.position)
    setWidthPercent(String(item.settings.layout.widthPercent))
    setHeightPercent(String(item.settings.layout.heightPercent))
    setXPercent(String(item.settings.layout.xPercent))
    setYPercent(String(item.settings.layout.yPercent))
    setTitle(item.settings.content.title)
    setPlaceholder(item.settings.content.placeholder)
    setText(item.settings.content.text)
  }, [])

  const loadElement = useCallback(async () => {
    if (!id || typeof id !== 'string') return

    setIsLoading(true)
    setErrorMessage('')

    try {
      const response = await axios.get(`/ui-elements/${id}`)
      const row = response?.data as UiElementRow

      if (!row?.id) {
        throw new Error('UI element not found.')
      }

      const normalized = normalizeUiElement(row)
      setElement(normalized)
      applyElementToForm(normalized)
    } catch (error: any) {
      const message = error?.response?.data?.message || error?.message || 'Failed to load UI element.'
      setErrorMessage(message)
      setElement(null)
      console.error('Failed to load UI element:', error)
    } finally {
      setIsLoading(false)
    }
  }, [applyElementToForm, id])

  useEffect(() => {
    loadElement()
  }, [loadElement])

  const toNumber = (value: string) => {
    const parsed = Number(value)
    return Number.isFinite(parsed) ? parsed : 0
  }

  const saveSettings = async () => {
    if (!element || !hasUpdatePermission) return

    setIsSaving(true)
    setErrorMessage('')

    try {
      const updatedSettings = {
        style: {
          ...element.settings.style,
          color,
          backgroundColor,
          border,
        },
        layout: {
          ...element.settings.layout,
          position,
          widthPercent: toNumber(widthPercent),
          heightPercent: toNumber(heightPercent),
          xPercent: toNumber(xPercent),
          yPercent: toNumber(yPercent),
        },
        content: {
          ...element.settings.content,
          title,
          placeholder,
          text,
        },
      }

      await axios.put(`/ui-elements/${element.id}`, {
        id: element.id,
        data: {
          name,
          settings_json: JSON.stringify(updatedSettings),
        },
      })

      const updatedElement = {
        ...element,
        name,
        settings: updatedSettings,
      }
      setElement(updatedElement)
      applyElementToForm(updatedElement)
    } catch (error: any) {
      const message = error?.response?.data?.message || error?.message || 'Failed to save UI element settings.'
      setErrorMessage(message)
      console.error('Failed to save UI element settings:', error)
    } finally {
      setIsSaving(false)
    }
  }

  return (
    <>
      <Head>
        <title>{getPageTitle('UI Element')}</title>
      </Head>
      <SectionMain>
        <SectionTitleLineWithButton icon={mdiPencil} title='UI Element Settings' main>
          {''}
        </SectionTitleLineWithButton>

        <CardBox className='mb-4'>
          <Link href='/ui-elements'>
            <BaseButton icon={mdiArrowLeft} label='Back to UI Elements' color='lightDark' />
          </Link>
        </CardBox>

        {errorMessage ? <CardBox className='mb-4 text-sm text-red-600'>{errorMessage}</CardBox> : null}

        {isLoading ? (
          <CardBox>
            <p className='text-sm text-gray-500'>Loading element settings...</p>
          </CardBox>
        ) : !element ? (
          <CardBox>
            <p className='text-sm text-gray-500'>UI element not found.</p>
          </CardBox>
        ) : (
          <>
            <CardBox className='mb-4'>
              <div className='mb-2 text-xs text-gray-500'>{toElementLabel(element.elementType)}</div>
              <div className='text-sm font-semibold'>{name || element.name}</div>
              <div className='mt-3'>
                <ElementPreview item={{ ...element, name, settings: { ...element.settings, style: { ...element.settings.style, color, backgroundColor, border }, content: { ...element.settings.content, text, title }, layout: { ...element.settings.layout, position, widthPercent: toNumber(widthPercent), heightPercent: toNumber(heightPercent), xPercent: toNumber(xPercent), yPercent: toNumber(yPercent) } } }} />
              </div>
            </CardBox>

            <CardBox className='mb-4'>
              <h3 className='mb-3 text-sm font-semibold'>General</h3>
              <div className='grid gap-4 md:grid-cols-2'>
                <div>
                  <label className='mb-1 block text-sm font-semibold'>Name</label>
                  <input
                    className='w-full rounded border border-gray-300 px-2 py-2 dark:border-dark-700 dark:bg-dark-800'
                    value={name}
                    onChange={(event) => setName(event.target.value)}
                    disabled={!hasUpdatePermission}
                  />
                </div>
                <div>
                  <label className='mb-1 block text-sm font-semibold'>Position</label>
                  <input
                    className='w-full rounded border border-gray-300 px-2 py-2 dark:border-dark-700 dark:bg-dark-800'
                    value={position}
                    onChange={(event) => setPosition(event.target.value)}
                    placeholder='absolute'
                    disabled={!hasUpdatePermission}
                  />
                </div>
              </div>
            </CardBox>

            <CardBox className='mb-4'>
              <h3 className='mb-3 text-sm font-semibold'>Style</h3>
              <div className='grid gap-4 md:grid-cols-3'>
                <div>
                  <label className='mb-1 block text-sm font-semibold'>Color</label>
                  <input
                    className='w-full rounded border border-gray-300 px-2 py-2 dark:border-dark-700 dark:bg-dark-800'
                    value={color}
                    onChange={(event) => setColor(event.target.value)}
                    placeholder='#111827'
                    disabled={!hasUpdatePermission}
                  />
                </div>
                <div>
                  <label className='mb-1 block text-sm font-semibold'>Background</label>
                  <input
                    className='w-full rounded border border-gray-300 px-2 py-2 dark:border-dark-700 dark:bg-dark-800'
                    value={backgroundColor}
                    onChange={(event) => setBackgroundColor(event.target.value)}
                    placeholder='#ffffff'
                    disabled={!hasUpdatePermission}
                  />
                </div>
                <div>
                  <label className='mb-1 block text-sm font-semibold'>Border</label>
                  <input
                    className='w-full rounded border border-gray-300 px-2 py-2 dark:border-dark-700 dark:bg-dark-800'
                    value={border}
                    onChange={(event) => setBorder(event.target.value)}
                    placeholder='1px solid #d1d5db'
                    disabled={!hasUpdatePermission}
                  />
                </div>
              </div>
            </CardBox>

            <CardBox className='mb-4'>
              <h3 className='mb-3 text-sm font-semibold'>Layout</h3>
              <div className='grid gap-4 md:grid-cols-4'>
                <div>
                  <label className='mb-1 block text-sm font-semibold'>Width %</label>
                  <input
                    className='w-full rounded border border-gray-300 px-2 py-2 dark:border-dark-700 dark:bg-dark-800'
                    value={widthPercent}
                    onChange={(event) => setWidthPercent(event.target.value)}
                    disabled={!hasUpdatePermission}
                  />
                </div>
                <div>
                  <label className='mb-1 block text-sm font-semibold'>Height %</label>
                  <input
                    className='w-full rounded border border-gray-300 px-2 py-2 dark:border-dark-700 dark:bg-dark-800'
                    value={heightPercent}
                    onChange={(event) => setHeightPercent(event.target.value)}
                    disabled={!hasUpdatePermission}
                  />
                </div>
                <div>
                  <label className='mb-1 block text-sm font-semibold'>X %</label>
                  <input
                    className='w-full rounded border border-gray-300 px-2 py-2 dark:border-dark-700 dark:bg-dark-800'
                    value={xPercent}
                    onChange={(event) => setXPercent(event.target.value)}
                    disabled={!hasUpdatePermission}
                  />
                </div>
                <div>
                  <label className='mb-1 block text-sm font-semibold'>Y %</label>
                  <input
                    className='w-full rounded border border-gray-300 px-2 py-2 dark:border-dark-700 dark:bg-dark-800'
                    value={yPercent}
                    onChange={(event) => setYPercent(event.target.value)}
                    disabled={!hasUpdatePermission}
                  />
                </div>
              </div>
            </CardBox>

            <CardBox className='mb-4'>
              <h3 className='mb-3 text-sm font-semibold'>Content</h3>
              <div className='grid gap-4 md:grid-cols-2'>
                <div>
                  <label className='mb-1 block text-sm font-semibold'>Title</label>
                  <input
                    className='w-full rounded border border-gray-300 px-2 py-2 dark:border-dark-700 dark:bg-dark-800'
                    value={title}
                    onChange={(event) => setTitle(event.target.value)}
                    disabled={!hasUpdatePermission}
                  />
                </div>
                <div>
                  <label className='mb-1 block text-sm font-semibold'>Placeholder</label>
                  <input
                    className='w-full rounded border border-gray-300 px-2 py-2 dark:border-dark-700 dark:bg-dark-800'
                    value={placeholder}
                    onChange={(event) => setPlaceholder(event.target.value)}
                    disabled={!hasUpdatePermission}
                  />
                </div>
                <div className='md:col-span-2'>
                  <label className='mb-1 block text-sm font-semibold'>Text</label>
                  <textarea
                    className='h-24 w-full rounded border border-gray-300 px-2 py-2 dark:border-dark-700 dark:bg-dark-800'
                    value={text}
                    onChange={(event) => setText(event.target.value)}
                    disabled={!hasUpdatePermission}
                  />
                </div>
              </div>
            </CardBox>

            <CardBox>
              <div className='flex items-center justify-end gap-2'>
                {!hasUpdatePermission ? <span className='text-xs text-gray-500'>Read-only access</span> : null}
                <BaseButton
                  color='info'
                  label={isSaving ? 'Saving...' : 'Save settings'}
                  onClick={saveSettings}
                  disabled={!hasUpdatePermission || isSaving}
                />
              </div>
            </CardBox>
          </>
        )}
      </SectionMain>
    </>
  )
}

UiElementDetailsPage.getLayout = function getLayout(page: ReactElement) {
  return <LayoutAuthenticated>{page}</LayoutAuthenticated>
}

export default UiElementDetailsPage
