import { type CSSProperties, useLayoutEffect, useMemo, useRef } from 'react'
import { useLocation, useNavigate } from 'react-router-dom'
import { lighten, withAlpha } from '../features/song-select/color-utils'
import { supabase } from '../lib/supabaseClient'
import { ROUTE_PATHS } from '../app/route-paths'
import { ArcadeDiscoReflect } from '../components/ArcadeDiscoReflect'
import { useLeaderboardStore } from '../stores/leaderboard/store'
import type { LeaderboardEntry, LeaderboardHighlight } from '../stores/leaderboard/types'
import { playSound, SFX_BUTTON_DEFAULT } from '../lib/sounds'
import styles from './LeaderboardPage.module.css'

const ACCENT_HEX = '#d946ef'

function gradeDataAttr(grade: string): 'S' | 'A' | 'B' | 'C' | 'D' | 'F' | 'other' {
  const g = grade.trim().toUpperCase().slice(0, 1)
  if (g === 'S' || g === 'A' || g === 'B' || g === 'C' || g === 'D' || g === 'F') {
    return g
  }
  return 'other'
}

function gradeLetter(grade: string): string {
  const t = grade.trim().toUpperCase()
  return t.slice(0, 1) || '?'
}

export function LeaderboardPage() {
  const navigate = useNavigate()
  const location = useLocation()
  const routeHighlight = (location.state as LeaderboardHighlight | null | undefined) ?? null

  const rows = useLeaderboardStore((state) => state.rows)
  const loading = useLeaderboardStore((state) => state.loading)
  const fetchError = useLeaderboardStore((state) => state.fetchError)
  const highlight = useLeaderboardStore((state) => state.highlight)
  const setRows = useLeaderboardStore((state) => state.setRows)
  const setLoading = useLeaderboardStore((state) => state.setLoading)
  const setFetchError = useLeaderboardStore((state) => state.setFetchError)
  const setHighlight = useLeaderboardStore((state) => state.setHighlight)

  const highlightedRef = useRef<HTMLLIElement>(null)

  const playAgainStyle = useMemo(
    () =>
      ({
        backgroundColor: lighten(ACCENT_HEX, 0.38),
        color: ACCENT_HEX,
      }) as CSSProperties,
    [],
  )

  const listPanelStyle = useMemo(
    () =>
      ({
        backgroundColor: withAlpha(ACCENT_HEX, 0.28),
        borderColor: withAlpha(ACCENT_HEX, 0.85),
      }) as CSSProperties,
    [],
  )

  useLayoutEffect(() => {
    if (!routeHighlight?.username || routeHighlight.score === undefined) return
    setHighlight(routeHighlight)
  }, [routeHighlight, setHighlight])

  useLayoutEffect(() => {
    let cancelled = false

    async function load() {
      setLoading(true)
      setFetchError(null)
      const { data, error } = await supabase
        .from('player_stats')
        .select('username, highscore, grade')
        .order('highscore', { ascending: false })

      if (cancelled) return

      if (error) {
        setFetchError(error.message || 'Failed to load leaderboard.')
        setRows([])
      } else {
        setRows((data as LeaderboardEntry[]) ?? [])
      }
      setLoading(false)
    }

    void load()
    return () => {
      cancelled = true
    }
  }, [])

  useLayoutEffect(() => {
    if (!highlight?.username || highlight.score === undefined) return
    if (loading || fetchError) return
    const el = highlightedRef.current
    if (el) {
      el.scrollIntoView({ block: 'center', behavior: 'smooth' })
    }
  }, [highlight, loading, fetchError, rows])

  function isHighlighted(row: LeaderboardEntry): boolean {
    return (
      highlight != null &&
      row.username === highlight.username &&
      row.highscore === highlight.score
    )
  }

  return (
    <div className={styles.root}>
      <div className={styles.vignette} aria-hidden="true" />
      <ArcadeDiscoReflect />
      <div className={styles.scanlines} aria-hidden="true" />

      <div className={styles.hud} aria-hidden="true">
        <span className={`${styles.hudCorner} ${styles.hudCornerTl}`} />
        <span className={`${styles.hudCorner} ${styles.hudCornerTr}`} />
        <span className={`${styles.hudCorner} ${styles.hudCornerBl}`} />
        <span className={`${styles.hudCorner} ${styles.hudCornerBr}`} />
        <div className={styles.hudCounter}>RANKINGS</div>
        <div className={styles.hudMetaLeft}>HIGH SCORE</div>
        <div className={styles.hudMetaRight}>ARCADE</div>
      </div>

      <div className={styles.shell}>
        <header className={styles.headerBlock}>
          <span className={styles.discoBall} aria-hidden="true" />
          <h1 className={`${styles.screenTitle} font-title`}>LEADERBOARD</h1>
          <p className={`${styles.subtitle} font-caption`}>TOP PLAYERS · GLOBAL RANKINGS</p>
        </header>

        <div className={styles.body}>
          <section className={styles.listPanel} style={listPanelStyle}>
            {loading ? (
              <div className={styles.centerMsg}>
                <div className={styles.spinner} role="status" aria-label="Loading" />
              </div>
            ) : fetchError ? (
              <div className={styles.centerMsg}>
                <p className={`${styles.msg} ${styles.msgError}`}>{fetchError}</p>
              </div>
            ) : rows.length === 0 ? (
              <div className={styles.centerMsg}>
                <p className={styles.msg}>No scores yet. Be the first!</p>
              </div>
            ) : (
              <>
                <div className={styles.listHead} role="row">
                  <span className={`${styles.colRank} font-caption`}>#</span>
                  <span className={`${styles.colName} font-caption`}>PLAYER</span>
                  <span className={`${styles.colScore} font-caption`}>SCORE</span>
                  <span className={`${styles.colGrade} font-caption`}>GRD</span>
                </div>
                <ul className={styles.list}>
                  {rows.map((row, index) => {
                    const rank = index + 1
                    const highlighted = isHighlighted(row)
                    const gKey = gradeDataAttr(row.grade)
                    const gLetter = gradeLetter(row.grade)

                    return (
                      <li
                        key={`${row.username}-${row.highscore}-${index}`}
                        ref={highlighted ? highlightedRef : undefined}
                        className={`${styles.row} ${highlighted ? styles.rowHighlighted : ''}`}
                      >
                        <div className={styles.rankWrap}>
                          {rank === 1 ? (
                            <span className={`${styles.rankBadge} ${styles.rankGold}`}>1</span>
                          ) : rank === 2 ? (
                            <span className={`${styles.rankBadge} ${styles.rankSilver}`}>2</span>
                          ) : rank === 3 ? (
                            <span className={`${styles.rankBadge} ${styles.rankBronze}`}>3</span>
                          ) : (
                            <span className={styles.rankNum}>{rank}</span>
                          )}
                        </div>
                        <p
                          className={`${styles.username} font-title ${rank === 1 ? styles.usernameTop : ''}`}
                        >
                          {row.username}
                        </p>
                        <span className={`${styles.score} font-display`}>
                          {row.highscore.toLocaleString()}
                        </span>
                        <span className={styles.gradeMini} data-grade={gKey}>
                          {gLetter}
                        </span>
                      </li>
                    )
                  })}
                </ul>
              </>
            )}
          </section>
        </div>

        <footer className={styles.footer}>
          <button
            type="button"
            className={`${styles.playAgain} font-title`}
            style={playAgainStyle}
            onClick={() => {
              playSound(SFX_BUTTON_DEFAULT)
              navigate(ROUTE_PATHS.home)
            }}
          >
            MAIN MENU
          </button>
        </footer>
      </div>
    </div>
  )
}
