import { useEffect, useState } from 'react'
import {
  ACTION_LABELS,
  INPUT_ACTIONS,
  useInput,
  type InputDevice,
} from '../input'
import {
  ControllerBindingLabel,
  ControllerStylePreview,
} from './ControllerIcons'

const CONTROLLER_STYLE_LABELS = {
  xbox: 'Xbox',
  playstation: 'PlayStation',
  nintendo: 'Nintendo',
} as const
import { useDualScreen } from '../dualScreen'
import {
  getNativeDisplays,
  hasNativeDualScreenBridge,
  type AndroidDisplay,
} from '../nativeDualScreen'

export function SettingsScreen({ onBack }: { onBack: () => void }) {
  const [device, setDevice] = useState<InputDevice>('controller')
  const [settingsTab, setSettingsTab] = useState<'display' | 'input' | 'bindings'>('display')
  const [displayMessage, setDisplayMessage] = useState('')
  const [androidDisplays, setAndroidDisplays] = useState<AndroidDisplay[]>([])
  const {
    bindings,
    capture,
    controllerIconStyle,
    directPartyTargeting,
    combatTouchLocked,
    beginCapture,
    cancelCapture,
    resetBindings,
    setControllerIconStyle,
    setDirectPartyTargeting,
    setCombatTouchLocked,
  } = useInput()
  const {
    enabled: dualScreenEnabled,
    connected: topDisplayConnected,
    setEnabled: setDualScreenEnabled,
    openTopDisplay,
  } = useDualScreen()
  const nativeDualScreen = hasNativeDualScreenBridge()
  const directTargetActions = new Set([
    'targetParty1',
    'targetParty2',
    'targetParty3',
    'targetParty4',
    'targetParty5',
    'targetParty6',
    'toggleTargetGroup',
  ])
  const visibleActions = INPUT_ACTIONS.filter((action) => (
    directPartyTargeting
      ? action !== 'previousTarget' && action !== 'nextTarget'
      : !directTargetActions.has(action)
  ))

  async function refreshNativeDisplays() {
    if (!nativeDualScreen) return
    try {
      const result = await getNativeDisplays()
      setAndroidDisplays(result.displays)
    } catch {
      setAndroidDisplays([])
    }
  }

  useEffect(() => {
    if (!nativeDualScreen) return
    getNativeDisplays()
      .then((result) => setAndroidDisplays(result.displays))
      .catch(() => setAndroidDisplays([]))
  }, [nativeDualScreen])

  async function launchTopDisplay() {
    const opened = await openTopDisplay()
    setDisplayMessage(opened
      ? nativeDualScreen
        ? 'Android placed the game on the larger display and controls on the smaller display.'
        : 'Companion display opened. Move it to the Thor screen you want and select Fullscreen.'
      : 'No usable second display was found. Check the Thor display mode and try again.')
    await refreshNativeDisplays()
  }

  return (
    <section className="content-screen settings-screen">
      <div className="screen-heading">
        <div>
          <p className="eyebrow">Game Options</p>
          <h1>Settings</h1>
        </div>
        <button className="back-button" onClick={onBack} type="button">Back</button>
      </div>

      <nav className="settings-tabs" role="tablist" aria-label="Settings sections">
        {([
          { key: 'display', label: 'Display' },
          { key: 'input', label: 'Input' },
          { key: 'bindings', label: 'Bindings' },
        ] as const).map((tab) => (
          <button
            aria-selected={settingsTab === tab.key}
            className={settingsTab === tab.key ? 'selected' : ''}
            key={tab.key}
            onClick={() => setSettingsTab(tab.key)}
            role="tab"
            type="button"
          >
            {tab.label}
          </button>
        ))}
      </nav>

      {settingsTab === 'display' && (
        <section className="dual-screen-settings settings-tab-panel">
          <div>
            <p className="eyebrow">Display</p>
            <h2>AYN Thor Dual-Screen Mode</h2>
            <p>
              The upper display shows enemy and party health. The lower display
              keeps targeting, resources, skills, and cooldowns.
            </p>
          </div>
          <div className="dual-screen-actions">
            <button
              className={dualScreenEnabled ? 'selected' : ''}
              onClick={() => {
                setDualScreenEnabled(!dualScreenEnabled)
                setDisplayMessage('')
              }}
              type="button"
            >
              {dualScreenEnabled ? 'Dual-Screen Enabled' : 'Enable Dual-Screen'}
            </button>
            <button onClick={launchTopDisplay} type="button">
              {topDisplayConnected ? 'Companion Connected' : 'Open Companion Display'}
            </button>
          </div>
          <small>
            {displayMessage || (
              topDisplayConnected
                ? 'The companion display is connected and receiving live combat data.'
                : 'Open the companion display before starting combat.'
            )}
          </small>
          {nativeDualScreen && androidDisplays.length > 0 && (
            <div className="android-display-list">
              {androidDisplays.map((display) => (
                <span key={display.id}>
                  <strong>{display.isCurrent ? 'Current' : 'Secondary'} #{display.id}</strong>
                  {display.width}x{display.height} at {Math.round(display.refreshRate)} Hz
                  {display.isPresentation ? ' - Presentation' : ''}
                </span>
              ))}
            </div>
          )}
        </section>
      )}

      {settingsTab === 'input' && (
        <section className="controller-preferences settings-tab-panel">
          <div>
            <p className="eyebrow">Targeting</p>
            <h3>Direct Party Keybinds</h3>
            <p>
              Assign party slots directly. In raids, use the group-switch binding
              to alternate between members 1-6, 7-12, and 13-18.
            </p>
          </div>
          <button
            aria-pressed={directPartyTargeting}
            className={directPartyTargeting ? 'selected' : ''}
            onClick={() => setDirectPartyTargeting(!directPartyTargeting)}
            type="button"
          >
            {directPartyTargeting ? 'Direct Targeting On' : 'Direct Targeting Off'}
          </button>
          <button
            aria-pressed={combatTouchLocked}
            className={combatTouchLocked ? 'selected' : ''}
            onClick={() => setCombatTouchLocked(!combatTouchLocked)}
            type="button"
          >
            {combatTouchLocked ? 'Combat Touch Locked' : 'Combat Touch Unlocked'}
          </button>
          <div className="controller-icon-options">
            <span>Controller Icons</span>
            {(['xbox', 'playstation', 'nintendo'] as const).map((style) => (
              <button
                aria-pressed={controllerIconStyle === style}
                className={controllerIconStyle === style ? 'selected' : ''}
                key={style}
                onClick={() => setControllerIconStyle(style)}
                type="button"
              >
                <ControllerStylePreview iconStyle={style} />
                <span className="controller-style-name">{CONTROLLER_STYLE_LABELS[style]}</span>
              </button>
            ))}
          </div>
        </section>
      )}

      {settingsTab === 'bindings' && (
        <section className="settings-bindings-panel settings-tab-panel">
          <div className="settings-heading">
            <div>
              <p className="eyebrow">Input</p>
              <h2>Keybindings</h2>
            </div>
            <p>Select an action, then press the new key or controller control.</p>
          </div>

          <div className="binding-tabs">
            <button
              className={device === 'controller' ? 'selected' : ''}
              onClick={() => setDevice('controller')}
              type="button"
            >
              Controller
            </button>
            <button
              className={device === 'pc' ? 'selected' : ''}
              onClick={() => setDevice('pc')}
              type="button"
            >
              PC
            </button>
          </div>

          <div className="binding-list">
            {visibleActions.map((action) => (
              <button
                className={capture?.device === device && capture.action === action ? 'listening' : ''}
                key={action}
                onClick={() => beginCapture(device, action)}
                type="button"
              >
                <span>{ACTION_LABELS[action]}</span>
                <kbd>
                  {capture?.device === device && capture.action === action
                    ? 'Press a control...'
                    : (
                      <ControllerBindingLabel
                        binding={bindings[device][action]}
                        iconStyle={controllerIconStyle}
                      />
                    )}
                </kbd>
              </button>
            ))}
          </div>

          <footer className="settings-footer">
            <span>Bindings are saved automatically on this device.</span>
            <button className="text-button" onClick={() => resetBindings(device)} type="button">
              Reset {device === 'pc' ? 'PC' : 'Controller'} Defaults
            </button>
          </footer>
        </section>
      )}

      {capture && (
        <div className="binding-capture" role="dialog" aria-modal="true">
          <div>
            <p className="eyebrow">Remapping</p>
            <h2>{ACTION_LABELS[capture.action]}</h2>
            <p>
              Press any {capture.device === 'pc' ? 'keyboard key' : 'controller button or move a stick'}.
            </p>
            <button onClick={cancelCapture} type="button">Cancel</button>
          </div>
        </div>
      )}
    </section>
  )
}
