// Title · Story · Briefing (dossier) · Boot — the "cold" pre-investigation screens.
import { useEffect, useRef, useState } from 'preact/hooks'
import type { ComponentChildren } from 'preact'

import { useTypewriter } from '../engine/pixel'
import { useGame } from '../store'
import type { PublicCase } from '../types'
import { playSfx } from '../ui/audio'
import { BottomNav, Btn, Controls, ExhibitArt, HintButton, Hud, Panel, Portrait, Scene, Stamp } from '../ui/components'

export function TitleScreen() {
  const g = useGame()
  const c = g.case
  const [enterId, setEnterId] = useState(false)
  const [idVal, setIdVal] = useState(c.id)
  const pull = () => {
    const id = idVal.trim()
    if (id) g.loadCase(id) // load that exact case (fresh run) and jump straight into it
  }
  return (
    <div class="app__view" style={{ position: 'relative' }}>
      <Scene name="skyline" w={320} h={200} anim cover style={{ position: 'absolute', inset: 0, width: '100%', height: '100%' }} />
      <div style={{ position: 'absolute', top: 12, right: 14, zIndex: 5 }}><Controls /></div>
      <div style={{ position: 'absolute', inset: 0, background: 'radial-gradient(90% 75% at 50% 42%, transparent 45%, rgba(8,11,16,.45) 95%)' }} />
      <div style={{ position: 'absolute', inset: 0, background: 'radial-gradient(34% 56% at 50% 46%, rgba(8,11,16,.82) 30%, rgba(8,11,16,.5) 60%, transparent 80%)' }} />
      <div style={{ position: 'relative', zIndex: 2, flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 26, padding: 24, textAlign: 'center' }}>
        <div class="t-label" style={{ letterSpacing: '.34em', color: 'var(--amber-2)' }}>A PROCEDURAL DETECTIVE MYSTERY</div>
        <h1 class="t-display" style={{ fontSize: 'clamp(34px,9vw,82px)', color: 'var(--bone-3)', lineHeight: 0.95, textShadow: '4px 4px 0 var(--ink-0)' }}>CASE<br />ZERO</h1>
        <p class="t-body" style={{ maxWidth: 440, color: 'var(--bone-2)', fontSize: 16 }}>
          Every case is generated. The city, the body, the lies. Solve one no one has ever seen.
        </p>
        <div class="t-mono amber" style={{ fontSize: 'calc(17px*var(--mono-scale))' }}>“{c.tagline}”</div>
        {!enterId ? (
          <div class="col" style={{ gap: 10, width: 'min(320px,80vw)', marginTop: 6 }}>
            <Btn variant="amber" onClick={() => g.newCase()}>▸ Begin New Case</Btn>
            <Btn variant="ghost" onClick={() => setEnterId(true)}>Enter Case ID</Btn>
            <Btn variant="ghost" onClick={() => g.nav('board')}>Continue · {c.id}</Btn>
          </div>
        ) : (
          <Panel className="col" style={{ gap: 10, width: 'min(340px,86vw)', padding: 16 }}>
            <span class="t-label">ENTER A CASE FILE NUMBER</span>
            <input
              class="pinput t-mono"
              value={idVal}
              onInput={(e) => setIdVal((e.target as HTMLInputElement).value)}
              style={{ textAlign: 'center', fontSize: 'calc(17px*var(--mono-scale))' }}
            />
            <div class="row" style={{ gap: 8 }}>
              <Btn variant="ghost" sm onClick={() => setEnterId(false)}>Back</Btn>
              <Btn variant="amber" className="grow" onClick={pull}>Pull File ▸</Btn>
            </div>
          </Panel>
        )}
      </div>
    </div>
  )
}

export function StoryScreen() {
  const g = useGame()
  const beats = g.case.storyBeats
  const [i, setI] = useState(0)
  const beat = beats[i]
  const last = i === beats.length - 1
  const [body, done] = useTypewriter(beat.text, (g.state.tweaks.typeSpeed || 18) + 2, true)
  return (
    <div class="app__view" style={{ position: 'relative', background: 'var(--ink-0)' }}>
      <Scene
        name={beat.scene}
        establishing={i === 0}
        incident={beat.incident ? g.case.kind || 'homicide' : undefined}
        anim
        w={320}
        h={200}
        cover
        deps={[i]}
        style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', opacity: beat.incident ? 0.75 : 0.5 }}
      />
      <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(180deg, rgba(8,11,16,.7) 0%, rgba(8,11,16,.35) 38%, rgba(8,11,16,.82) 100%)' }} />
      <div style={{ position: 'relative', zIndex: 2, flex: 1, display: 'flex', flexDirection: 'column' }}>
        <div class="between" style={{ padding: '14px 18px' }}>
          <span class="t-label" style={{ letterSpacing: '.2em', color: 'var(--amber-2)' }}>{beat.kicker}</span>
          <div class="row" style={{ gap: 8 }}>
            <HintButton />
            <Btn sm variant="ghost" onClick={() => g.nav('board')}>Skip ▸</Btn>
          </div>
        </div>
        <div class="grow center" style={{ padding: '12px 22px' }}>
          <div style={{ maxWidth: 680, width: '100%' }}>
            <h1 class="t-display" style={{ fontSize: 'clamp(22px,4vw,34px)', color: 'var(--bone-3)', marginBottom: 18, lineHeight: 1.1, textShadow: '3px 3px 0 var(--ink-0)' }}>{beat.title}</h1>
            <p class="t-body" style={{ fontSize: 'clamp(16px,2.2vw,20px)', lineHeight: 1.65, color: 'var(--bone-2)', minHeight: 130 }}>
              {body}
              {!done && <span class="cursor" />}
            </p>
          </div>
        </div>
        <div class="between" style={{ padding: '16px 22px 22px', gap: 14 }}>
          <div class="row" style={{ gap: 6 }}>
            {beats.map((_, k) => (
              <span key={k} onClick={() => setI(k)} style={{ width: 26, height: 6, cursor: 'pointer', background: k === i ? 'var(--amber-2)' : k < i ? 'var(--slate-2)' : 'var(--ink-3)', boxShadow: 'inset 0 0 0 1px var(--ink-0)' }} />
            ))}
          </div>
          <div class="row" style={{ gap: 10 }}>
            {i > 0 && <Btn variant="ghost" onClick={() => setI(i - 1)}>◂ Back</Btn>}
            {!last ? (
              <Btn variant="amber" onClick={() => setI(i + 1)}>Next ▸</Btn>
            ) : (
              <Btn variant="amber" style={{ padding: '13px 24px' }} onClick={() => g.nav('board')}>Start Investigating ▸▸</Btn>
            )}
          </div>
        </div>
      </div>
    </div>
  )
}

export function BootScreen() {
  const g = useGame()
  const boot = g.case.bootLines
  const [lines, setLines] = useState<string[]>([])
  const [cur, setCur] = useState('')
  const [stamped, setStamped] = useState(false)
  const [done, setDone] = useState(false)
  const idx = useRef(0)
  const ch = useRef(0)

  useEffect(() => {
    const speed = g.state.tweaks.typeSpeed || 16
    let timer: ReturnType<typeof setTimeout>
    const tick = () => {
      const i = idx.current
      if (i >= boot.length) {
        setStamped(true)
        setTimeout(() => setDone(true), 900)
        return
      }
      const line = boot[i]
      ch.current++
      setCur(line.slice(0, ch.current))
      if (ch.current >= line.length) {
        setLines((l) => [...l, line])
        setCur('')
        ch.current = 0
        idx.current++
        timer = setTimeout(tick, 240)
      } else {
        timer = setTimeout(tick, speed)
      }
    }
    timer = setTimeout(tick, 300)
    return () => clearTimeout(timer)
  }, [])

  return (
    <div class="app__view" style={{ position: 'relative', background: 'var(--ink-0)' }}>
      <Scene name={g.case.district} establishing w={320} h={200} cover style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', opacity: 0.28 }} />
      <div style={{ position: 'absolute', inset: 0, background: 'radial-gradient(90% 80% at 30% 40%, transparent 40%, rgba(8,11,16,.7) 100%)' }} />
      <div class="screen-center" style={{ position: 'relative', zIndex: 2 }}>
        <div class="maxw" style={{ maxWidth: 760, display: 'flex', flexDirection: 'column', gap: 22, alignItems: g.mode === 'mobile' ? 'stretch' : 'flex-start' }}>
          <div class="row" style={{ gap: 10, alignItems: 'center' }}>
            <span style={{ width: 9, height: 9, background: 'var(--ox-3)', boxShadow: '0 0 10px var(--ox-3)', animation: 'blink 1.4s steps(1) infinite' }} />
            <span class="t-label" style={{ letterSpacing: '.22em', color: 'var(--amber-2)' }}>{g.case.city} · {g.case.district}</span>
          </div>
          <div class="t-mono" style={{ fontSize: 'calc(17px*var(--mono-scale))', lineHeight: 1.85, color: 'var(--bone-2)', minHeight: g.mode === 'mobile' ? 220 : 200 }}>
            {lines.map((l, i) => (
              <div key={i} style={{ opacity: i === lines.length - 1 && !cur ? 1 : 0.82 }}>{l}</div>
            ))}
            {cur && <div class="bone">{cur}<span class="cursor" /></div>}
            {lines.length === 0 && !cur && <span class="cursor" />}
          </div>
          <div class="col" style={{ gap: 18, alignItems: g.mode === 'mobile' ? 'stretch' : 'flex-start' }}>
            <div style={{ position: 'relative', paddingTop: 16 }}>
              <span class="t-label" style={{ position: 'absolute', top: 0, left: 0 }}>CASE FILE No.</span>
              {stamped ? (
                <Stamp slam style={{ fontSize: 'clamp(15px,3.5vw,22px)' }}>{g.case.id}</Stamp>
              ) : (
                <span class="t-display dim" style={{ fontSize: 'clamp(15px,3.5vw,22px)', opacity: 0.25, letterSpacing: '.08em' }}>— — — — —</span>
              )}
            </div>
            {done && <Btn variant="amber" style={{ fontSize: 12, padding: '15px 24px' }} onClick={() => g.nav('briefing')}>Take the Case ▸</Btn>}
          </div>
        </div>
      </div>
    </div>
  )
}

// ---- dossier ----
function PageHead({ tab, idx, c }: { tab: string; idx: string; c: PublicCase }) {
  return (
    <div class="between" style={{ borderBottom: '2px solid #211d1533', paddingBottom: 10, marginBottom: 16 }}>
      <div class="col" style={{ gap: 4 }}>
        <span class="dlabel">{c.city} CO. · {c.division || 'HOMICIDE DIVISION'}</span>
        <span class="dh" style={{ fontSize: 13 }}>{tab}</span>
      </div>
      <span class="dtype" style={{ fontSize: 'calc(13px*var(--mono-scale))', color: '#6a6150' }}>FILE {c.id} · pg.{idx}</span>
    </div>
  )
}

function dossierPages(c: PublicCase): { tab: string; render: () => ComponentChildren }[] {
  return [
    {
      tab: 'COVER',
      render: () => (
        <div class="center" style={{ flexDirection: 'column', height: '100%', gap: 18, textAlign: 'center', position: 'relative' }}>
          <span class="paperclip" />
          <span class="dlabel" style={{ fontSize: 9, letterSpacing: '.3em' }}>{c.district}</span>
          <div class="dlabel" style={{ color: '#6a6150', letterSpacing: '.2em' }}>{c.kindLabel || 'HOMICIDE'} — CASE FILE</div>
          <h1 class="dh" style={{ fontSize: 'clamp(26px,5vw,44px)', lineHeight: 1.05 }}>{c.title}</h1>
          <div style={{ margin: '6px 0' }}><span class="dstamp" style={{ fontSize: 'clamp(14px,3vw,20px)' }}>{c.id}</span></div>
          <div class="dtype" style={{ color: '#4a4234' }}>{c.district}</div>
          <div style={{ position: 'absolute', bottom: 6, right: 8 }}><span class="dstamp" style={{ fontSize: 11, borderColor: '#1a1610', color: '#1a1610', transform: 'rotate(4deg)' }}>CONFIDENTIAL</span></div>
          <div class="dtype" style={{ color: '#6a6150', fontSize: 'calc(14px*var(--mono-scale))', marginTop: 8 }}>▸ flip the page →</div>
        </div>
      ),
    },
    {
      tab: 'THE VICTIM',
      render: () => (
        <div>
          <PageHead tab="THE VICTIM" idx="01" c={c} />
          <div class="row" style={{ gap: 20, alignItems: 'flex-start', flexWrap: 'wrap' }}>
            <div class="photo-paper" style={{ flexShrink: 0 }}>
              <div style={{ background: '#0d1117', padding: 4 }}><Portrait id={c.victim.sprite} px={6} /></div>
              <div class="dtype" style={{ fontSize: 'calc(12px*var(--mono-scale))', color: '#6a6150', textAlign: 'center', marginTop: 4 }}>{c.victim.name.split(' ').slice(-1)[0]}</div>
            </div>
            <div class="col" style={{ gap: 8, flex: 1, minWidth: 200 }}>
              <h2 class="dh" style={{ fontSize: 20 }}>{c.victim.name}</h2>
              <div class="dtype" style={{ color: '#4a4234' }}>{c.victim.role}</div>
              <div class="row" style={{ gap: 10, flexWrap: 'wrap' }}>
                <span class="dstamp" style={{ fontSize: 11 }}>{c.victimStatus || 'DECEASED'}</span>
                <span class="dtype" style={{ alignSelf: 'center' }}>{c.todLabel || 'T.O.D.'} {c.tod} · AGE {c.victim.age}</span>
              </div>
            </div>
          </div>
          <hr style={{ border: 0, borderTop: '2px dashed #211d1533', margin: '16px 0' }} />
          <p class="dtype">{c.victim.bio}</p>
        </div>
      ),
    },
    {
      tab: 'THE SCENE',
      render: () => (
        <div>
          <PageHead tab="THE SCENE" idx="02" c={c} />
          <div class="photo-paper" style={{ marginBottom: 16, transform: 'rotate(-1deg)' }}>
            <div style={{ aspectRatio: '16/9', background: '#0d1117' }}>
              <Scene name={c.scene} w={288} h={162} style={{ width: '100%', height: '100%' }} />
            </div>
            <div class="dtype" style={{ fontSize: 'calc(12px*var(--mono-scale))', color: '#6a6150', marginTop: 4 }}>EXHIBIT A — {c.scene}</div>
          </div>
          <p class="dtype" style={{ marginBottom: 10 }}><b style={{ color: '#8a3a2c' }}>FOUND — </b>{c.found}</p>
          <p class="dtype"><b style={{ color: '#8a3a2c' }}>CAUSE — </b>{c.cause}</p>
        </div>
      ),
    },
    {
      tab: 'THE EXHIBITS',
      render: () => (
        <div>
          <PageHead tab="THE EXHIBITS" idx="03" c={c} />
          <p class="dtype" style={{ marginBottom: 12, color: '#4a4234' }}>Photographed and logged at the scene. Examine each on the wall.</p>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
            {c.evidence.slice(0, 6).map((e, i) => (
              <div key={e.id} class="photo-paper" style={{ transform: `rotate(${(i % 3) - 1}deg)` }}>
                <div style={{ background: '#0d1117' }}>
                  <ExhibitArt e={e} style={{ width: '100%', height: 'auto' }} />
                </div>
                <div class="between" style={{ marginTop: 4, gap: 6 }}>
                  <span class="dtype" style={{ fontSize: 'calc(11px*var(--mono-scale))', color: '#6a6150', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{e.name}</span>
                  <span class="dtype" style={{ fontSize: 'calc(11px*var(--mono-scale))', color: '#8a3a2c', flexShrink: 0 }}>{e.time}</span>
                </div>
              </div>
            ))}
          </div>
        </div>
      ),
    },
    {
      tab: 'KEY FACTS',
      render: () => (
        <div style={{ position: 'relative' }}>
          <PageHead tab="KEY FACTS" idx="04" c={c} />
          <div style={{ position: 'absolute', top: 60, right: 0 }}><span class="dstamp" style={{ fontSize: 13 }}>{c.kindLabel || 'HOMICIDE'}</span></div>
          <div class="col" style={{ gap: 0 }}>
            {c.facts.map(([k, v], i) => (
              <div key={i} class="row" style={{ gap: 14, padding: '11px 0', borderBottom: '1px dotted #211d1540', alignItems: 'baseline' }}>
                <span class="dlabel" style={{ color: '#6a6150', width: 116, flexShrink: 0 }}>{k}</span>
                <span class="dtype" style={{ color: k === 'VERDICT' ? '#8a2a2a' : '#211d15' }}>{v}</span>
              </div>
            ))}
          </div>
        </div>
      ),
    },
    {
      tab: 'PERSONS OF INTEREST',
      render: () => (
        <div>
          <PageHead tab="PERSONS OF INTEREST" idx="05" c={c} />
          <p class="dtype" style={{ marginBottom: 14, color: '#4a4234' }}>Those who stayed when the others fled the sirens. Each had reason to be near.</p>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
            {c.suspects.map((s) => (
              <div key={s.id} class="row" style={{ gap: 10, alignItems: 'center', background: '#00000010', padding: 8, boxShadow: 'inset 0 0 0 1px #211d1522' }}>
                <div style={{ background: '#0d1117', padding: 3, flexShrink: 0 }}><Portrait id={s.sprite} px={3} gender={s.gender} accent={s.accentColor} /></div>
                <div class="col" style={{ gap: 2, minWidth: 0 }}>
                  <span class="dh" style={{ fontSize: 10 }}>{s.name}</span>
                  <span class="dlabel" style={{ color: '#8a3a2c' }}>{s.tag}</span>
                </div>
              </div>
            ))}
          </div>
          <p class="dtype" style={{ marginTop: 16, color: '#8a3a2c', textAlign: 'center' }}>One of them is lying. Find the crack.</p>
        </div>
      ),
    },
  ]
}

export function BriefingScreen() {
  const g = useGame()
  const c = g.case
  const PAGES = dossierPages(c)
  const [page, setPage] = useState(0)
  const [flip, setFlip] = useState<string | null>(null)
  const go = (dir: number) => {
    const next = page + dir
    if (next < 0 || next >= PAGES.length) return
    playSfx('page')
    setFlip(dir > 0 ? 'fwd' : 'back')
    setPage(next)
    setTimeout(() => setFlip(null), 470)
  }
  const P = PAGES[page]
  return (
    <div class="app__view">
      <Hud title={c.title} sub="CASE DOSSIER" />
      <div class="dossier-stage">
        <div class="dossier">
          <div class="dossier__folder">
            <div class="page-wrap">
              <div class={'page ' + (page % 2 ? 'page--paper2 ' : '') + (flip ? 'page--flip-' + flip : '')} key={page}>
                {P.render()}
                <div class="page__curl" />
                {page > 0 && <div class="page__edge page__edge--l" onClick={() => go(-1)} title="Previous page" />}
                {page < PAGES.length - 1 && <div class="page__edge page__edge--r" onClick={() => go(1)} title="Next page" />}
              </div>
            </div>
          </div>
          <div class="dossier__nav">
            <Btn sm variant="ghost" sfx={null} disabled={page === 0} onClick={() => go(-1)}>◂ Prev</Btn>
            <div class="page-dots">
              {PAGES.map((pg, i) => (
                <span key={i} class={'page-dot' + (i === page ? ' page-dot--on' : '')} title={pg.tab}
                  onClick={() => { setFlip(i > page ? 'fwd' : 'back'); setPage(i); setTimeout(() => setFlip(null), 470) }} />
              ))}
            </div>
            {page < PAGES.length - 1 ? (
              <Btn sm variant="amber" sfx={null} onClick={() => go(1)}>Next page ▸</Btn>
            ) : (
              <Btn variant="amber" onClick={() => g.nav('board')}>Open the Wall ▸▸</Btn>
            )}
          </div>
        </div>
      </div>
      <BottomNav />
    </div>
  )
}
