import { useEffect, useState } from 'react'
import './App.css'

type Pair = {
  id: number
  playerA: string
  playerB: string
}

type DrawResult = {
  pairs: Pair[]
  benchA: string[]
  benchB: string[]
}

const STORAGE_KEYS = {
  areaA: 'badminton-match-hub::area-a',
  areaB: 'badminton-match-hub::area-b',
} as const

const defaultAreaA = ['小杰', '阿誠', '建宏', '柏宇', 'Eason']
const defaultAreaB = ['小安', '佩珊', '阿廷', 'Luna', 'Mina']

function App() {
  const [areaAInput, setAreaAInput] = useState(() =>
    loadRoster(STORAGE_KEYS.areaA, defaultAreaA),
  )
  const [areaBInput, setAreaBInput] = useState(() =>
    loadRoster(STORAGE_KEYS.areaB, defaultAreaB),
  )
  const [result, setResult] = useState<DrawResult | null>(null)
  const [error, setError] = useState('')

  useEffect(() => {
    window.localStorage.setItem(STORAGE_KEYS.areaA, areaAInput)
  }, [areaAInput])

  useEffect(() => {
    window.localStorage.setItem(STORAGE_KEYS.areaB, areaBInput)
  }, [areaBInput])

  const parsedAreaA = parseRoster(areaAInput)
  const parsedAreaB = parseRoster(areaBInput)

  function generateMatches() {
    if (parsedAreaA.length < 3 || parsedAreaB.length < 3) {
      setResult(null)
      setError('A 區與 B 區都至少要有 3 位不重複成員，才能產生三組配對。')
      return
    }

    const shuffledA = shuffleList(parsedAreaA)
    const shuffledB = shuffleList(parsedAreaB)
    const selectedA = shuffledA.slice(0, 3)
    const selectedB = shuffledB.slice(0, 3)

    const pairs = selectedA.map((playerA, index) => ({
      id: index + 1,
      playerA,
      playerB: selectedB[index],
    }))

    setResult({
      pairs,
      benchA: shuffledA.slice(3),
      benchB: shuffledB.slice(3),
    })
    setError('')
  }

  function resetDemo() {
    setAreaAInput(defaultAreaA.join('\n'))
    setAreaBInput(defaultAreaB.join('\n'))
    setResult(null)
    setError('')
  }

  return (
    <main className="app-shell">
      <section className="hero-card">
        <div className="hero-copy">
          <p className="eyebrow">使用 React、Vite 與 TypeScript 建置</p>
          <h1>羽毛球隊伍配對器</h1>
          <p className="hero-text">
            分別輸入 A 區與 B 區名單後，系統會從兩區各抽出 3 位成員，
            自動組成 3 組隊伍。每一組都是 A 區 1 位搭配 B 區 1 位，
            同一輪內三組成員都不會重複。
          </p>
          <div className="hero-actions">
            <button className="primary-button" type="button" onClick={generateMatches}>
              產生三組配對
            </button>
            <button className="ghost-button" type="button" onClick={resetDemo}>
              載入範例名單
            </button>
          </div>
        </div>

        <div className="hero-stats">
          <article className="stat-card">
            <span>A 區可用人數</span>
            <strong>{parsedAreaA.length}</strong>
          </article>
          <article className="stat-card">
            <span>B 區可用人數</span>
            <strong>{parsedAreaB.length}</strong>
          </article>
          <article className="tip-card">
            <h2>配對規則</h2>
            <p>固定產生 3 組，且每組皆為 A 區 1 位加上 B 區 1 位，當輪不重複。</p>
          </article>
        </div>
      </section>

      <section className="content-grid">
        <article className="panel">
          <div className="panel-heading">
            <p className="eyebrow">名單輸入</p>
            <h2>輸入 A 區與 B 區成員</h2>
          </div>

          <div className="input-grid">
            <label className="roster-field">
              <span>A 區成員</span>
              <textarea
                value={areaAInput}
                onChange={(event) => setAreaAInput(event.target.value)}
                placeholder={'每行一位\n例如：小杰'}
                rows={10}
              />
            </label>

            <label className="roster-field">
              <span>B 區成員</span>
              <textarea
                value={areaBInput}
                onChange={(event) => setAreaBInput(event.target.value)}
                placeholder={'每行一位\n例如：小安'}
                rows={10}
              />
            </label>
          </div>

          <p className="helper-text">
            支援換行、半形逗號、全形逗號與頓號分隔，系統會自動去除空白與重複名稱。
          </p>

          {error ? <p className="error-banner">{error}</p> : null}
        </article>

        <article className="panel">
          <div className="panel-heading">
            <p className="eyebrow">配對結果</p>
            <h2>本輪三組隊伍</h2>
          </div>

          {result ? (
            <div className="pair-list">
              {result.pairs.map((pair) => (
                <article className="pair-card" key={pair.id}>
                  <div className="pair-index">第 {pair.id} 組</div>
                  <div className="pair-names">
                    <div className="player-chip player-chip-a">
                      <span className="chip-label">A 區</span>
                      <strong>{pair.playerA}</strong>
                    </div>
                    <div className="pair-link">+</div>
                    <div className="player-chip player-chip-b">
                      <span className="chip-label">B 區</span>
                      <strong>{pair.playerB}</strong>
                    </div>
                  </div>
                </article>
              ))}
            </div>
          ) : (
            <div className="empty-state">
              <p>輸入名單後按下「產生三組配對」，這裡會顯示本輪的抽籤結果。</p>
            </div>
          )}
        </article>
      </section>

      <section className="bench-grid">
        <article className="panel">
          <div className="panel-heading">
            <p className="eyebrow">候補名單</p>
            <h2>A 區未出場成員</h2>
          </div>
          <RosterList
            names={result?.benchA ?? parsedAreaA.slice(3)}
            emptyText="目前沒有 A 區候補成員"
          />
        </article>

        <article className="panel">
          <div className="panel-heading">
            <p className="eyebrow">候補名單</p>
            <h2>B 區未出場成員</h2>
          </div>
          <RosterList
            names={result?.benchB ?? parsedAreaB.slice(3)}
            emptyText="目前沒有 B 區候補成員"
          />
        </article>
      </section>
    </main>
  )
}

type RosterListProps = {
  names: string[]
  emptyText: string
}

function RosterList({ names, emptyText }: RosterListProps) {
  if (names.length === 0) {
    return <p className="empty-inline">{emptyText}</p>
  }

  return (
    <div className="name-list">
      {names.map((name) => (
        <span className="name-pill" key={name}>
          {name}
        </span>
      ))}
    </div>
  )
}

function loadRoster(storageKey: string, fallbackList: string[]) {
  const storedValue = window.localStorage.getItem(storageKey)
  return storedValue && storedValue.trim() ? storedValue : fallbackList.join('\n')
}

function parseRoster(input: string) {
  const uniqueNames = new Set<string>()

  input
    .split(/[\n,，、]+/g)
    .map((name) => name.trim())
    .filter(Boolean)
    .forEach((name) => uniqueNames.add(name))

  return Array.from(uniqueNames)
}

function shuffleList(list: string[]) {
  const next = [...list]

  for (let index = next.length - 1; index > 0; index -= 1) {
    const swapIndex = Math.floor(Math.random() * (index + 1))
    ;[next[index], next[swapIndex]] = [next[swapIndex], next[index]]
  }

  return next
}

export default App
