// frontend/src/pages/melodies/MelodySettings.jsx

import { useState, useEffect } from 'react'
import PageHeader from '@/components/ui/PageHeader'
import Card from '@/components/ui/Card'
import Button from '@/components/ui/Button'
import FormField from '@/components/ui/FormField'
import Spinner from '@/components/ui/Spinner'
import Modal from '@/components/ui/Modal'
import { useToast } from '@/components/ui/Toast'
import api from '@/lib/api'
import {
  LANGUAGE_MASTER_LIST,
  getLanguageName,
  formatDuration,
  normalizeColor,
} from '@/lib/melodyUtils'

// ─── Constants ───────────────────────────────────────────────────────────────

const DEFAULT_NOTE_COLORS = [
  '#67E8F9', '#5EEAD4', '#6EE7B7', '#86EFAC',
  '#BEF264', '#FDE68A', '#FCD34D', '#FBBF24',
  '#FDBA74', '#FB923C', '#F97316', '#FB7185',
  '#F87171', '#EF4444', '#DC2626', '#B91C1C',
]

const NOTE_LABELS = 'ABCDEFGHIJKLMNOP'

// ─── Component ────────────────────────────────────────────────────────────────

export default function MelodySettings() {
  const { toast } = useToast()

  const [settings,       setSettings]       = useState(null)
  const [loading,        setLoading]        = useState(true)
  const [saving,         setSaving]         = useState(false)
  const [fetchError,     setFetchError]     = useState('')

  // Note color modal
  const [colorModalBell,  setColorModalBell]  = useState(null)
  const [modalColor,      setModalColor]      = useState('#67E8F9')
  const [modalHexInput,   setModalHexInput]   = useState('#67E8F9')

  // Add language
  const [langToAdd, setLangToAdd] = useState('')

  // Add quick color
  const [quickColorPicker, setQuickColorPicker] = useState('#c0c1ff')
  const [quickColorHex,    setQuickColorHex]    = useState('#c0c1ff')

  // Add duration
  const [durationInput, setDurationInput] = useState('')

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

  const loadSettings = async () => {
    setLoading(true)
    setFetchError('')
    try {
      const data = await api.get('/settings/melody')
      setSettings({
        ...data,
        note_assignment_colors: (data.note_assignment_colors || DEFAULT_NOTE_COLORS).slice(0, 16),
      })
    } catch (err) {
      setFetchError(err.message || 'Failed to load settings.')
    } finally {
      setLoading(false)
    }
  }

  const save = async (updated) => {
    setSaving(true)
    try {
      const result = await api.put('/settings/melody', updated)
      setSettings(result)
      toast.success('Saved', 'Settings updated.')
    } catch (err) {
      toast.danger('Error', err.message || 'Failed to save.')
    } finally {
      setSaving(false)
    }
  }

  // ── Languages ─────────────────────────────────────────────────────────────

  const addLanguage = () => {
    if (!langToAdd || settings.available_languages.includes(langToAdd)) return
    save({ ...settings, available_languages: [...settings.available_languages, langToAdd] })
    setLangToAdd('')
  }

  const removeLanguage = (code) => {
    if (settings.available_languages.length <= 1) return
    save({
      ...settings,
      available_languages: settings.available_languages.filter((c) => c !== code),
      primary_language:
        settings.primary_language === code
          ? settings.available_languages.find((c) => c !== code)
          : settings.primary_language,
    })
  }

  const setPrimaryLanguage = (code) => save({ ...settings, primary_language: code })

  // ── Quick colors ──────────────────────────────────────────────────────────

  const addQuickColor = () => {
    const color = quickColorHex.startsWith('#') ? quickColorHex : `#${quickColorHex}`
    if (!/^#[0-9A-Fa-f]{6}$/.test(color)) return
    if (settings.quick_colors.includes(color)) return
    save({ ...settings, quick_colors: [...settings.quick_colors, color] })
  }

  const removeQuickColor = (color) =>
    save({ ...settings, quick_colors: settings.quick_colors.filter((c) => c !== color) })

  // ── Duration presets ──────────────────────────────────────────────────────

  const addDuration = () => {
    const val = parseInt(durationInput, 10)
    if (isNaN(val) || val < 0) return
    if (settings.duration_values.includes(val)) return
    save({ ...settings, duration_values: [...settings.duration_values, val].sort((a, b) => a - b) })
    setDurationInput('')
  }

  const removeDuration = (val) =>
    save({ ...settings, duration_values: settings.duration_values.filter((v) => v !== val) })

  // ── Note assignment colors ────────────────────────────────────────────────

  const openNoteColorModal = (index) => {
    const current = settings.note_assignment_colors?.[index] || DEFAULT_NOTE_COLORS[index]
    setModalColor(current)
    setModalHexInput(current)
    setColorModalBell(index)
  }

  const applyNoteColor = () => {
    if (colorModalBell == null) return
    const candidate = modalHexInput.startsWith('#') ? modalHexInput : `#${modalHexInput}`
    if (!/^#[0-9A-Fa-f]{6}$/.test(candidate)) return
    const next = [...(settings.note_assignment_colors || DEFAULT_NOTE_COLORS)]
    next[colorModalBell] = candidate
    save({ ...settings, note_assignment_colors: next.slice(0, 16) })
    setColorModalBell(null)
  }

  const resetNoteColor = () => {
    const fallback = DEFAULT_NOTE_COLORS[colorModalBell]
    setModalColor(fallback)
    setModalHexInput(fallback)
  }

  // ── Render ────────────────────────────────────────────────────────────────

  if (loading) {
    return (
      <div className="page-wrapper">
        <PageHeader title="Melody Settings" subtitle="Configure global melody behaviour and defaults." />
        <div style={{ display: 'flex', justifyContent: 'center', padding: 'var(--space-16)' }}>
          <Spinner size="lg" />
        </div>
      </div>
    )
  }

  if (fetchError || !settings) {
    return (
      <div className="page-wrapper">
        <PageHeader title="Melody Settings" />
        <div style={{
          padding: 'var(--space-4)',
          backgroundColor: 'var(--color-danger-bg)',
          border: '1px solid var(--color-danger)',
          borderRadius: 'var(--radius-md)',
          color: 'var(--color-danger)',
          fontSize: 'var(--font-size-sm)',
        }}>
          {fetchError || 'Failed to load settings.'}
        </div>
      </div>
    )
  }

  const availableToAdd = LANGUAGE_MASTER_LIST.filter(
    (l) => !settings.available_languages.includes(l.code)
  )

  return (
    <div className="page-wrapper">
      <PageHeader title="Melody Settings" subtitle="Configure global melody behaviour and defaults." />

      <div className="grid grid-cols-1 xl:grid-cols-2 gap-6">

        {/* ── Languages ─────────────────────────────────────────────────── */}
        <Card title="Available Languages" subtitle="Languages shown in the melody editor and detail view.">
          <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-2)', marginBottom: 'var(--space-4)' }}>
            {settings.available_languages.map((code) => (
              <div key={code} style={{
                display: 'flex', alignItems: 'center', justifyContent: 'space-between',
                padding: 'var(--space-2) var(--space-3)',
                backgroundColor: 'var(--color-bg-elevated)',
                borderRadius: 'var(--radius-md)',
              }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-3)' }}>
                  <span style={{ fontFamily: 'var(--font-family-mono)', fontSize: 'var(--font-size-xs)', color: 'var(--color-text-muted)', textTransform: 'uppercase', width: 24 }}>
                    {code}
                  </span>
                  <span style={{ fontSize: 'var(--font-size-sm)', color: 'var(--color-text-primary)' }}>
                    {getLanguageName(code)}
                  </span>
                  {settings.primary_language === code && (
                    <span style={{
                      fontSize: 'var(--font-size-xs)', fontWeight: 'var(--font-weight-semibold)',
                      padding: '1px var(--space-2)', borderRadius: 'var(--radius-full)',
                      backgroundColor: 'var(--color-primary-subtle)', color: 'var(--color-primary)',
                    }}>
                      Primary
                    </span>
                  )}
                </div>
                <div style={{ display: 'flex', gap: 'var(--space-2)' }}>
                  {settings.primary_language !== code && (
                    <Button variant="ghost" size="sm" disabled={saving} onClick={() => setPrimaryLanguage(code)}>
                      Set Primary
                    </Button>
                  )}
                  {settings.available_languages.length > 1 && (
                    <Button variant="danger" size="sm" disabled={saving} onClick={() => removeLanguage(code)}>
                      Remove
                    </Button>
                  )}
                </div>
              </div>
            ))}
          </div>

          <div style={{ display: 'flex', gap: 'var(--space-2)' }}>
            <div style={{ flex: 1 }}>
              <FormField
                label="Add Language"
                name="lang-add"
                type="select"
                value={langToAdd}
                onChange={(e) => setLangToAdd(e.target.value)}
              >
                <option value="">Select language…</option>
                {availableToAdd.map((l) => (
                  <option key={l.code} value={l.code}>{l.name} ({l.code})</option>
                ))}
              </FormField>
            </div>
            <div style={{ alignSelf: 'flex-end', paddingBottom: 1 }}>
              <Button variant="primary" disabled={!langToAdd || saving} loading={saving} onClick={addLanguage}>
                Add
              </Button>
            </div>
          </div>
        </Card>

        {/* ── Quick Colors ──────────────────────────────────────────────── */}
        <Card title="Quick Selection Colors" subtitle="Color swatches shown in the melody color picker.">
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 'var(--space-2)', marginBottom: 'var(--space-4)' }}>
            {settings.quick_colors.map((color) => (
              <div key={color} style={{ position: 'relative' }} className="group">
                <div
                  style={{
                    width: 40, height: 40,
                    borderRadius: 'var(--radius-md)',
                    backgroundColor: normalizeColor(color),
                    border: '2px solid var(--color-border)',
                    boxShadow: `0 0 8px 1px ${color}44`,
                    cursor: 'default',
                  }}
                  title={color}
                />
                <button
                  type="button"
                  disabled={saving}
                  onClick={() => removeQuickColor(color)}
                  style={{
                    position: 'absolute', top: -6, right: -6,
                    width: 18, height: 18,
                    borderRadius: '50%',
                    backgroundColor: 'var(--color-danger)',
                    color: 'var(--color-text-inverse)',
                    border: 'none', cursor: 'pointer',
                    fontSize: 11, lineHeight: 1,
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                    opacity: 0,
                    transition: 'opacity 120ms',
                  }}
                  className="group-hover:opacity-100"
                >
                  ×
                </button>
              </div>
            ))}
          </div>

          <div style={{ display: 'flex', alignItems: 'flex-end', gap: 'var(--space-2)' }}>
            <input
              type="color"
              value={quickColorPicker}
              onChange={(e) => { setQuickColorPicker(e.target.value); setQuickColorHex(e.target.value) }}
              style={{ width: 42, height: 42, borderRadius: 'var(--radius-md)', border: '1px solid var(--color-border)', cursor: 'pointer', padding: 2, backgroundColor: 'var(--color-bg-abyss)' }}
            />
            <div style={{ flex: 1 }}>
              <FormField
                label="Hex code"
                name="quick-color-hex"
                type="text"
                value={quickColorHex}
                onChange={(e) => {
                  setQuickColorHex(e.target.value)
                  if (/^#[0-9A-Fa-f]{6}$/.test(e.target.value)) setQuickColorPicker(e.target.value)
                }}
                placeholder="#RRGGBB"
                inputProps={{ style: { fontFamily: 'var(--font-family-mono)' } }}
              />
            </div>
            <div style={{ paddingBottom: 1 }}>
              <Button variant="primary" disabled={saving} onClick={addQuickColor}>Add</Button>
            </div>
          </div>
        </Card>

        {/* ── Duration Presets ──────────────────────────────────────────── */}
        <Card title="Duration Presets" subtitle="Available durations (in seconds) shown in the melody editor." className="xl:col-span-2">
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 'var(--space-2)', marginBottom: 'var(--space-4)' }}>
            {settings.duration_values.map((val) => (
              <div
                key={val}
                style={{
                  display: 'inline-flex', alignItems: 'center', gap: 'var(--space-2)',
                  padding: 'var(--space-2) var(--space-3)',
                  borderRadius: 'var(--radius-full)',
                  backgroundColor: 'var(--color-bg-elevated)',
                  border: '1px solid var(--color-border)',
                }}
              >
                <span style={{ fontSize: 'var(--font-size-sm)', color: 'var(--color-text-primary)' }}>
                  {formatDuration(val)}
                </span>
                <span style={{ fontSize: 'var(--font-size-xs)', color: 'var(--color-text-muted)', fontFamily: 'var(--font-family-mono)' }}>
                  {val}s
                </span>
                <button
                  type="button"
                  disabled={saving}
                  onClick={() => removeDuration(val)}
                  style={{
                    background: 'transparent', border: 'none',
                    color: 'var(--color-danger)', cursor: 'pointer',
                    fontSize: 'var(--font-size-sm)', lineHeight: 1,
                    padding: 0,
                  }}
                >
                  ×
                </button>
              </div>
            ))}
          </div>

          <div style={{ display: 'flex', alignItems: 'flex-end', gap: 'var(--space-2)' }}>
            <div style={{ width: 180 }}>
              <FormField
                label="Seconds"
                name="duration-add"
                type="number"
                value={durationInput}
                onChange={(e) => setDurationInput(e.target.value)}
                placeholder="e.g. 45"
                inputProps={{
                  min: 0,
                  onKeyDown: (e) => { if (e.key === 'Enter') { e.preventDefault(); addDuration() } },
                }}
              />
            </div>
            <div style={{ paddingBottom: 1 }}>
              <Button variant="primary" disabled={saving || !durationInput} onClick={addDuration}>Add</Button>
            </div>
          </div>
        </Card>

        {/* ── Note Assignment Colors ─────────────────────────────────────── */}
        <Card
          title="Note Assignment Colors"
          subtitle="Colors used in the Composer grid and playback visualiser. Click a bell to customize."
          className="xl:col-span-2"
        >
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(80px, 1fr))', gap: 'var(--space-3)' }}>
            {Array.from({ length: 16 }, (_, idx) => {
              const color = settings.note_assignment_colors?.[idx] || DEFAULT_NOTE_COLORS[idx]
              return (
                <button
                  key={idx}
                  type="button"
                  onClick={() => openNoteColorModal(idx)}
                  style={{
                    display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 'var(--space-2)',
                    padding: 'var(--space-3) var(--space-2)',
                    backgroundColor: 'var(--color-bg-elevated)',
                    border: '1px solid var(--color-border)',
                    borderRadius: 'var(--radius-lg)',
                    cursor: 'pointer',
                    transition: 'background 120ms, border-color 120ms',
                  }}
                  onMouseEnter={(e) => { e.currentTarget.style.backgroundColor = 'var(--color-bg-island)'; e.currentTarget.style.borderColor = 'var(--color-border-strong)' }}
                  onMouseLeave={(e) => { e.currentTarget.style.backgroundColor = 'var(--color-bg-elevated)'; e.currentTarget.style.borderColor = 'var(--color-border)' }}
                  title={`Bell ${idx + 1} — ${color}`}
                >
                  <span style={{
                    display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                    width: 32, height: 32, borderRadius: '50%',
                    backgroundColor: color,
                    color: '#111827',
                    fontSize: 'var(--font-size-xs)',
                    fontWeight: 'var(--font-weight-bold)',
                    boxShadow: `0 0 10px 2px ${color}55`,
                  }}>
                    {NOTE_LABELS[idx]}
                  </span>
                  <span style={{
                    fontFamily: 'var(--font-family-mono)',
                    fontSize: 10,
                    color: 'var(--color-text-muted)',
                    letterSpacing: 0,
                  }}>
                    {color.toLowerCase()}
                  </span>
                </button>
              )
            })}
          </div>
        </Card>

      </div>

      {/* ── Note Color Modal ──────────────────────────────────────────────── */}
      <Modal
        open={colorModalBell != null}
        onClose={() => setColorModalBell(null)}
        title={colorModalBell != null ? `Bell ${colorModalBell + 1} — ${NOTE_LABELS[colorModalBell]} Color` : ''}
        size="sm"
        footer={
          <div style={{ display: 'flex', gap: 'var(--space-2)', justifyContent: 'space-between', width: '100%' }}>
            <Button variant="ghost" size="sm" onClick={resetNoteColor}>Reset Default</Button>
            <div style={{ display: 'flex', gap: 'var(--space-2)' }}>
              <Button variant="secondary" onClick={() => setColorModalBell(null)}>Cancel</Button>
              <Button variant="primary" onClick={applyNoteColor} loading={saving}>Apply</Button>
            </div>
          </div>
        }
      >
        <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-4)' }}>
          <p style={{ margin: 0, fontSize: 'var(--font-size-sm)', color: 'var(--color-text-muted)' }}>
            Pick a custom color for this bell note in the composer and playback views.
          </p>

          <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-3)' }}>
            <input
              type="color"
              value={modalColor}
              onChange={(e) => { setModalColor(e.target.value); setModalHexInput(e.target.value) }}
              style={{ width: 56, height: 44, borderRadius: 'var(--radius-md)', border: '1px solid var(--color-border)', cursor: 'pointer', padding: 2, backgroundColor: 'var(--color-bg-abyss)', flexShrink: 0 }}
            />
            <div style={{ flex: 1 }}>
              <FormField
                label="Hex code"
                name="modal-color-hex"
                type="text"
                value={modalHexInput}
                onChange={(e) => {
                  setModalHexInput(e.target.value)
                  if (/^#[0-9A-Fa-f]{6}$/.test(e.target.value)) setModalColor(e.target.value)
                }}
                inputProps={{ style: { fontFamily: 'var(--font-family-mono)' } }}
              />
            </div>
            {/* Preview swatch */}
            <span style={{
              flexShrink: 0,
              width: 40, height: 40, borderRadius: '50%',
              backgroundColor: modalColor,
              boxShadow: `0 0 12px 3px ${modalColor}66`,
              display: 'inline-block',
            }} />
          </div>
        </div>
      </Modal>
    </div>
  )
}
