import { useEffect, useRef, useState } from 'react'
import {
  allocateTalent,
  resetTalents,
  type CharacterProfile,
  type Talent,
} from '../profile'
import { useDualScreen, useDualScreenWorkshopPublisher, type DualScreenWorkshopState } from '../dualScreen'

type Props = {
  profile: CharacterProfile
  onBack?: () => void
  onUpdated: (profile: CharacterProfile) => void
  embedded?: boolean
}

const EFFECT_SLOT_LEVELS = [5, 10, 15, 20] as const
const EFFECT_CLASS_ID = 1
const EFFECTS_PER_PAGE = 8
const EFFECT_SOURCE_LABELS: Record<string, string> = {
  mend: 'Mend',
  radiance: 'Radiance',
  shield: 'Shield',
}

function effectSource(effectType: string) {
  if (effectType.startsWith('mend_')) return 'mend'
  if (effectType.startsWith('radiance_')) return 'radiance'
  if (effectType.startsWith('shield_') || effectType.startsWith('shielded_')) return 'shield'
  return effectType
}

function effectCapacity(level: number) {
  return EFFECT_SLOT_LEVELS.filter((slotLevel) => level >= slotLevel).length
}

function activeEffects(talents: Talent[]) {
  return talents.filter((talent) => talent.rank > 0)
}

export function TalentScreen({ profile, onBack, onUpdated, embedded = false }: Props) {
  const { enabled: dualScreenEnabled } = useDualScreen()
  const [busyTalentId, setBusyTalentId] = useState<number | null>(null)
  const [resetting, setResetting] = useState(false)
  const [selectedTalentId, setSelectedTalentId] = useState<number | null>(null)
  const [effectPage, setEffectPage] = useState(0)
  const [message, setMessage] = useState('')
  const scrollRef = useRef<number>(0)
  const gameClass = profile.classes.find(
    (candidate) => candidate.id === profile.character.classId,
  )!
  const isEffectClass = gameClass.id === EFFECT_CLASS_ID
  const capacity = isEffectClass ? effectCapacity(profile.character.level) : 0
  const selectedEffects = activeEffects(gameClass.talents)
  const selectedTalent = gameClass.talents.find((talent) => talent.id === selectedTalentId)
    ?? selectedEffects[0]
    ?? gameClass.talents[0]
    ?? null
  const effectPageCount = Math.max(1, Math.ceil(gameClass.talents.length / EFFECTS_PER_PAGE))
  const activeEffectPage = Math.min(effectPage, effectPageCount - 1)
  const visibleTalents = gameClass.talents.slice(
    activeEffectPage * EFFECTS_PER_PAGE,
    activeEffectPage * EFFECTS_PER_PAGE + EFFECTS_PER_PAGE,
  )

  useEffect(() => {
    window.scrollTo(0, scrollRef.current)
  }, [profile])

  function saveScroll() {
    scrollRef.current = window.scrollY
  }

  function lockReason(talent: Talent) {
    if (!isEffectClass) return 'Coming soon'
    if (talent.rank > 0) return ''
    const source = effectSource(talent.effectType)
    const sourceConflict = selectedEffects.find((effect) => effectSource(effect.effectType) === source)
    if (sourceConflict) return `${EFFECT_SOURCE_LABELS[source] ?? source} already selected`
    if (capacity <= 0) return 'Unlocks at level 5'
    if (selectedEffects.length >= capacity) {
      return `Active slots full (${capacity}/${capacity})`
    }
    return ''
  }

  async function toggleEffect(talent: Talent) {
    saveScroll()
    setBusyTalentId(talent.id)
    setMessage('')
    try {
      const updated = await allocateTalent(talent.id)
      onUpdated(updated)
      setSelectedTalentId(talent.id)
      setMessage(talent.rank > 0 ? `${talent.name} removed.` : `${talent.name} activated.`)
    } catch (reason) {
      setMessage(reason instanceof Error ? reason.message : 'Unable to update spell effect.')
    } finally {
      setBusyTalentId(null)
    }
  }

  async function clearEffects() {
    saveScroll()
    setResetting(true)
    setMessage('')
    try {
      const updated = await resetTalents()
      onUpdated(updated)
      setMessage('Spell effects cleared.')
    } catch (reason) {
      setMessage(reason instanceof Error ? reason.message : 'Unable to clear spell effects.')
    } finally {
      setResetting(false)
    }
  }

  const workshopState: DualScreenWorkshopState | null = isEffectClass
    ? {
      mode: 'talents',
      title: 'Spell Effects',
      subtitle: `${selectedEffects.length}/${capacity} active`,
      summary: selectedTalent
        ? `${selectedTalent.name}: ${selectedTalent.description}`
        : 'Choose effects to modify your spells.',
      items: gameClass.talents.map((talent) => ({
        glyph: talent.glyph,
        title: talent.name,
        meta: talent.rank > 0 ? 'Active' : lockReason(talent) || 'Available',
        detail: talent.description,
        status: talent.rank > 0 ? 'Selected' : '',
      })),
    }
    : null

  useDualScreenWorkshopPublisher(workshopState, dualScreenEnabled)

  const content = (
    <>
      {!embedded && (
        <div className="screen-heading">
          <div>
            <p className="eyebrow">Character Growth</p>
            <h1>Spell Effects</h1>
          </div>
          <button className="back-button" onClick={onBack} type="button">Back</button>
        </div>
      )}
      <div className="talent-toolbar spell-effect-toolbar">
        <div className="talent-class-summary">
          <span style={{ borderColor: gameClass.themeColor, color: gameClass.themeColor }}>
            {gameClass.name[0]}
          </span>
          <div>
            <p className="eyebrow">{gameClass.name} Effects</p>
            <h2>Modify Your Spells</h2>
          </div>
        </div>
        <div className="talent-points">
          <strong>{selectedEffects.length}/{capacity}</strong>
          <span>Active</span>
          <small>Slots unlock at levels 5, 10, 15, 20</small>
        </div>
      </div>

      {!isEffectClass ? (
        <div className="talent-empty-state">
          <h2>Spell effects coming soon for {gameClass.name}.</h2>
          <p>This replacement system starts with the first class.</p>
        </div>
      ) : (
        <div className="spell-effect-layout">
          <section className="effect-slots-panel">
            <p className="eyebrow">Active Slots</p>
            {EFFECT_SLOT_LEVELS.map((level, index) => {
              const effect = selectedEffects[index]
              const unlocked = profile.character.level >= level
              return (
                <button
                  className={`effect-slot ${effect ? 'filled' : ''} ${unlocked ? '' : 'locked'}`}
                  disabled={!effect}
                  key={level}
                  onClick={() => effect && setSelectedTalentId(effect.id)}
                  type="button"
                >
                  <span>Lv {level}</span>
                  <strong>{effect?.name ?? (unlocked ? 'Empty Slot' : 'Locked')}</strong>
                  <small>{effect?.description ?? (unlocked ? 'Choose an effect from the pool.' : `Reach level ${level}.`)}</small>
                </button>
              )
            })}
          </section>

          <section className="effect-pool-panel">
            <div className="effect-panel-heading">
              <div>
                <p className="eyebrow">Effect Pool</p>
                <h2>Choose and Swap</h2>
              </div>
              <span>{selectedEffects.length}/{capacity} active</span>
            </div>
            <div className="selected-effect-strip">
              <div>
                <p className="eyebrow">Selected Effect</p>
                {selectedTalent ? (
                  <>
                    <strong>{selectedTalent.name}</strong>
                    <small>{selectedTalent.description}</small>
                  </>
                ) : (
                  <small>No effect selected.</small>
                )}
              </div>
              {selectedTalent && (
                <button
                  className="primary-button"
                  disabled={Boolean(lockReason(selectedTalent)) || busyTalentId === selectedTalent.id}
                  onClick={() => toggleEffect(selectedTalent)}
                  type="button"
                >
                  {busyTalentId === selectedTalent.id
                    ? 'Saving...'
                    : selectedTalent.rank > 0
                      ? 'Remove'
                      : 'Activate'}
                </button>
              )}
            </div>
            <div className="effect-pool">
              {visibleTalents.map((talent) => {
                const reason = lockReason(talent)
                const active = talent.rank > 0
                const selected = selectedTalent?.id === talent.id
                const isBusy = busyTalentId === talent.id
                return (
                  <button
                    className={`${active ? 'active' : ''} ${selected ? 'selected' : ''}`}
                    disabled={Boolean(reason) || isBusy}
                    key={talent.id}
                    onClick={() => {
                      setSelectedTalentId(talent.id)
                      void toggleEffect(talent)
                    }}
                    type="button"
                  >
                    <span>{talent.glyph}</span>
                    <div>
                      <strong>{talent.name}</strong>
                      <small>{EFFECT_SOURCE_LABELS[effectSource(talent.effectType)] ?? 'Spell'}</small>
                    </div>
                    <i>{isBusy ? 'Saving' : active ? 'Active' : reason || 'Available'}</i>
                  </button>
                )
              })}
            </div>
            {effectPageCount > 1 && (
              <div className="effect-pager">
                <button
                  disabled={activeEffectPage === 0}
                  onClick={() => setEffectPage(Math.max(0, activeEffectPage - 1))}
                  type="button"
                >
                  Prev
                </button>
                <span>{activeEffectPage + 1}/{effectPageCount}</span>
                <button
                  disabled={activeEffectPage >= effectPageCount - 1}
                  onClick={() => setEffectPage(Math.min(effectPageCount - 1, activeEffectPage + 1))}
                  type="button"
                >
                  Next
                </button>
              </div>
            )}
          </section>
        </div>
      )}

      <footer className="talent-footer">
        <span>{message || 'Spell effect changes are saved immediately.'}</span>
        <button
          className="text-button"
          disabled={selectedEffects.length === 0 || resetting}
          onClick={clearEffects}
          type="button"
        >
          {resetting ? 'Clearing...' : 'Clear Effects'}
        </button>
      </footer>
    </>
  )

  if (embedded) {
    return <div className="talent-screen embedded-screen">{content}</div>
  }

  return (
    <section className="content-screen talent-screen">
      {content}
    </section>
  )
}
