import { useEffect, useState } from 'react'
import { ChevronDown, ChevronUp, Plus, Trash2 } from 'lucide-react'
import { Breadcrumbs } from '../components/Breadcrumbs'
import { StepColorPicker } from '../components/StepColorPicker'
import { Switch } from '../components/Switch'
import { Tooltip } from '../components/Tooltip'
import { useToast } from '../context/ToastContext'
import { useT } from '../i18n/useT'
import { ApiError } from '../lib/api'
import {
  getSettings,
  updateStoreSettings,
  DEFAULT_ORDER_PROCESS_STEPS,
  type OrderProcessStep,
  type StoreSettings,
} from '../services/settingsService'
import { createId } from '../utils/id'
import {
  defaultStepColorForId,
  normalizeStepColor,
  type StepColorPreset,
} from '../utils/stepColors'
import controlStyles from '../components/CategoryRow.module.css'
import removeStyles from '../components/VariationsModal.module.css'
import pageStyles from '../components/PageContent.module.css'
import sharedStyles from './ProductSettingsPage.module.css'
import styles from './StoreSettingsPage.module.css'

const DEFAULT_STORE_SETTINGS: StoreSettings = {
  onlineSellEnabled: true,
  orderProcessSteps: DEFAULT_ORDER_PROCESS_STEPS,
}

function normalizeSteps(steps: OrderProcessStep[]) {
  return steps.map((step, index) => ({
    id: step.id,
    label: step.label.trim(),
    labelFa: (step.labelFa ?? '').trim(),
    color: normalizeStepColor(step.color, defaultStepColorForId(step.id, index)),
  }))
}

function stepsAreEqual(a: OrderProcessStep[], b: OrderProcessStep[]) {
  if (a.length !== b.length) return false
  return a.every((step, index) => {
    const other = b[index]
    return (
      step.id === other.id &&
      step.label === other.label &&
      step.labelFa === other.labelFa &&
      step.color === other.color
    )
  })
}

export function StoreSettingsPage() {
  const t = useT()
  const { showToast } = useToast()
  const [settings, setSettings] = useState<StoreSettings>(DEFAULT_STORE_SETTINGS)
  const [draftSteps, setDraftSteps] = useState<OrderProcessStep[]>(
    DEFAULT_STORE_SETTINGS.orderProcessSteps,
  )
  const [isLoading, setIsLoading] = useState(true)
  const [savingKey, setSavingKey] = useState<string | null>(null)
  const [error, setError] = useState('')

  useEffect(() => {
    const controller = new AbortController()
    void loadSettings(controller.signal)
    return () => controller.abort()
  }, [])

  async function loadSettings(signal?: AbortSignal) {
    setIsLoading(true)
    setError('')

    try {
      const data = await getSettings(signal)
      setSettings(data.settings.store)
      setDraftSteps(data.settings.store.orderProcessSteps)
    } catch (err) {
      if (err instanceof DOMException && err.name === 'AbortError') return
      if (err instanceof ApiError) {
        setError(err.message)
      } else {
        setError(t('productSettings.errorLoad'))
      }
    } finally {
      setIsLoading(false)
    }
  }

  async function handleOnlineSellChange(checked: boolean) {
    setSavingKey('onlineSell')
    setError('')

    try {
      const data = await updateStoreSettings({ onlineSellEnabled: checked })
      setSettings(data.settings.store)
      showToast(t('productSettings.saved'), 'success')
    } catch (err) {
      if (err instanceof ApiError) {
        setError(err.message)
      } else {
        setError(t('productSettings.errorSave'))
      }
    } finally {
      setSavingKey(null)
    }
  }

  function updateStepLabel(id: string, label: string) {
    setDraftSteps((current) =>
      current.map((step) => (step.id === id ? { ...step, label } : step)),
    )
  }

  function updateStepLabelFa(id: string, labelFa: string) {
    setDraftSteps((current) =>
      current.map((step) => (step.id === id ? { ...step, labelFa } : step)),
    )
  }

  function updateStepColor(id: string, color: StepColorPreset) {
    setDraftSteps((current) =>
      current.map((step) => (step.id === id ? { ...step, color } : step)),
    )
  }

  function addStep() {
    setDraftSteps((current) => {
      const id = createId()
      return [
        ...current,
        {
          id,
          label: '',
          labelFa: '',
          color: defaultStepColorForId(id, current.length),
        },
      ]
    })
  }

  function removeStep(id: string) {
    setDraftSteps((current) => current.filter((step) => step.id !== id))
  }

  function moveStep(id: string, direction: -1 | 1) {
    setDraftSteps((current) => {
      const index = current.findIndex((step) => step.id === id)
      if (index < 0) return current

      const targetIndex = index + direction
      if (targetIndex < 0 || targetIndex >= current.length) return current

      const next = [...current]
      const [item] = next.splice(index, 1)
      next.splice(targetIndex, 0, item)
      return next
    })
  }

  async function handleSaveSteps() {
    const normalized = normalizeSteps(draftSteps)
    const hasEmptyLabel = normalized.some((step) => !step.label || !step.labelFa)
    if (!normalized.length) {
      setError(t('storeSettings.error.minSteps'))
      return
    }
    if (hasEmptyLabel) {
      setError(t('storeSettings.error.labels'))
      return
    }

    setSavingKey('orderSteps')
    setError('')

    try {
      const data = await updateStoreSettings({ orderProcessSteps: normalized })
      setSettings(data.settings.store)
      setDraftSteps(data.settings.store.orderProcessSteps)
      showToast(t('storeSettings.stepsSaved'), 'success')
    } catch (err) {
      if (err instanceof ApiError) {
        setError(err.message)
      } else {
        setError(t('storeSettings.error.saveSteps'))
      }
    } finally {
      setSavingKey(null)
    }
  }

  const stepsDirty = !stepsAreEqual(
    normalizeSteps(draftSteps),
    normalizeSteps(settings.orderProcessSteps),
  )
  const canSaveSteps =
    stepsDirty &&
    draftSteps.length > 0 &&
    draftSteps.every(
      (step) => step.label.trim().length > 0 && step.labelFa.trim().length > 0,
    )

  return (
    <main className={pageStyles.content}>
      <Breadcrumbs
        items={[
          { label: 'Dashboard', href: '/' },
          { label: 'Store', href: '/store' },
          { label: 'Settings' },
        ]}
      />

      <div className={pageStyles.pageHeader}>
        <div>
          <h2 className={pageStyles.pageTitle}>{t('storeSettings.title')}</h2>
          <p className={pageStyles.pageSubtitle}>{t('storeSettings.subtitle')}</p>
        </div>
      </div>

      {error && (
        <div className={sharedStyles.alertError} role="alert">
          {error}
        </div>
      )}

      <section className={sharedStyles.panel}>
        {isLoading ? (
          <p className={sharedStyles.status}>{t('productSettings.loading')}</p>
        ) : (
          <div className={sharedStyles.list}>
            <div className={sharedStyles.row}>
              <div className={sharedStyles.rowText}>
                <label htmlFor="online-sell" className={sharedStyles.rowLabel}>
                  {t('storeSettings.onlineSell')}
                </label>
                <p className={sharedStyles.rowDescription}>
                  {t('storeSettings.onlineSellDesc')}
                </p>
              </div>
              <Switch
                id="online-sell"
                checked={settings.onlineSellEnabled}
                disabled={savingKey === 'onlineSell'}
                aria-label={t('storeSettings.onlineSell')}
                onChange={(checked) => void handleOnlineSellChange(checked)}
              />
            </div>
          </div>
        )}
      </section>

      <section className={`${sharedStyles.panel} ${styles.stepsPanel}`}>
        <div className={styles.stepsHeader}>
          <div>
            <h3 className={sharedStyles.sectionTitle}>{t('storeSettings.orderProcess')}</h3>
            <p className={styles.stepsDescription}>{t('storeSettings.orderProcessDesc')}</p>
          </div>
        </div>

        {isLoading ? (
          <p className={sharedStyles.status}>{t('productSettings.loading')}</p>
        ) : (
          <>
            <div className={styles.stepsList}>
              {draftSteps.map((step, index) => (
                <div key={step.id} className={styles.stepRow}>
                  <span className={styles.stepIndex}>{index + 1}</span>
                  <StepColorPicker
                    value={normalizeStepColor(step.color, defaultStepColorForId(step.id, index))}
                    onChange={(color) => updateStepColor(step.id, color)}
                    ariaLabel={t('storeSettings.stepColorAria', { index: index + 1 })}
                  />
                  <input
                    type="text"
                    className={styles.stepInput}
                    value={step.label}
                    placeholder={t('storeSettings.labelEn')}
                    aria-label={t('storeSettings.stepEnAria', { index: index + 1 })}
                    dir="ltr"
                    lang="en"
                    onChange={(e) => updateStepLabel(step.id, e.target.value)}
                  />
                  <input
                    type="text"
                    className={`${styles.stepInput} ${styles.stepInputFa}`}
                    value={step.labelFa ?? ''}
                    placeholder={t('storeSettings.labelFa')}
                    aria-label={t('storeSettings.stepFaAria', { index: index + 1 })}
                    dir="rtl"
                    lang="fa"
                    onChange={(e) => updateStepLabelFa(step.id, e.target.value)}
                  />
                  <div className={styles.stepControls}>
                    <Tooltip label={t('storeSettings.moveUp')}>
                      <button
                        type="button"
                        className={controlStyles.controlBtn}
                        onClick={() => moveStep(step.id, -1)}
                        disabled={index === 0}
                        aria-label={t('storeSettings.moveUp')}
                      >
                        <ChevronUp size={16} />
                      </button>
                    </Tooltip>
                    <Tooltip label={t('storeSettings.moveDown')}>
                      <button
                        type="button"
                        className={controlStyles.controlBtn}
                        onClick={() => moveStep(step.id, 1)}
                        disabled={index === draftSteps.length - 1}
                        aria-label={t('storeSettings.moveDown')}
                      >
                        <ChevronDown size={16} />
                      </button>
                    </Tooltip>
                    <Tooltip label={t('storeSettings.removeStep')}>
                      <button
                        type="button"
                        className={removeStyles.removeRowBtn}
                        onClick={() => removeStep(step.id)}
                        disabled={draftSteps.length <= 1}
                        aria-label={t('storeSettings.removeStep')}
                      >
                        <Trash2 size={15} />
                      </button>
                    </Tooltip>
                  </div>
                </div>
              ))}

              {!draftSteps.length && (
                <p className={styles.emptyText}>{t('storeSettings.emptySteps')}</p>
              )}
            </div>

            <button type="button" className={styles.addStepBtn} onClick={addStep}>
              <Plus size={18} />
              {t('storeSettings.addStep')}
            </button>

            <div className={styles.stepsActions}>
              <button
                type="button"
                className={styles.saveBtn}
                onClick={() => void handleSaveSteps()}
                disabled={!canSaveSteps || savingKey === 'orderSteps'}
              >
                {savingKey === 'orderSteps'
                  ? t('storeSettings.saving')
                  : t('storeSettings.saveSteps')}
              </button>
            </div>
          </>
        )}
      </section>
    </main>
  )
}
