import React from 'react';
import './App.css';
import DeathwatchRoller from './components/DeathwatchRoller';
import RequisitionShop from './components/RequisitionShop';
import PlayerTab from './components/PlayerTab';
import RulesTab from './components/RulesTab';
import BestiaryTab from './components/BestiaryTab';
import WeaponsTab from './components/WeaponsTab';
import GMKit from './components/GMKit';
import PlayerManagement from './components/PlayerManagement';
import MissionTab from './components/MissionTab';
import SimulationTab from './components/SimulationTab';
import ErrorReports from './components/ErrorReports';
import BattlemapTab from './components/BattlemapTab';
import { useState, useEffect } from 'react';
import axios from 'axios';
import { debug, info, warn, error, logApiCall, logApiError, logUserAction } from './utils/logger';

function App() {
  const [tab, setTab] = useState('mission');
  // Global login/session state
  const [authedPlayer, setAuthedPlayer] = useState(() => localStorage.getItem('dw:shop:authedPlayer') ? JSON.parse(localStorage.getItem('dw:shop:authedPlayer')) : '');
  const [sessionId, setSessionId] = useState(() => localStorage.getItem('dw:shop:sessionId') ? JSON.parse(localStorage.getItem('dw:shop:sessionId')) : '');
  const [loginName, setLoginName] = useState('');
  const [loginPw, setLoginPw] = useState('');
  const [loginMsg, setLoginMsg] = useState('');
  const [players, setPlayers] = useState([]);
  const [playersError, setPlayersError] = useState('');



  // Fetch player list for login (exposed so UI can refresh)
  async function fetchPlayers() {
    try {
      setPlayersError('')
      const res = await axios.get('/api/players/names');
      setPlayers(res.data || []);
    } catch (err) {
      console.error('fetchPlayers failed', err);
      setPlayers([]);
      setPlayersError('Failed to load users — is the backend running? Check console/network.');
    }
  }

  // Fetch players on mount
  useEffect(() => {
    fetchPlayers();
  }, []);

  useEffect(() => {
    function openRollerFromMission() {
      setTab('roller');
    }
    window.addEventListener('dw:open-roller', openRollerFromMission);
    return () => window.removeEventListener('dw:open-roller', openRollerFromMission);
  }, []);

  // Validate session on mount/refresh
  useEffect(() => {
    async function validate() {
      if (sessionId) {
        try {
          debug(`Validating session: ${sessionId}`, 'auth');
          const res = await axios.post('/api/sessions/validate', { sessionId });
          logApiCall('POST', '/api/sessions/validate', { sessionId }, res.status);
          
          if (res.data && res.data.playerName) {
            setAuthedPlayer(res.data.playerName);
            localStorage.setItem('dw:shop:authedPlayer', JSON.stringify(res.data.playerName));
            
            // Fetch full player data for the validated session
            try {
              const fullPlayerResponse = await axios.get(`/api/players/${res.data.playerName}`, {
                headers: { 'x-session-id': sessionId }
              });
              localStorage.setItem('dw:shop:playerData', JSON.stringify(fullPlayerResponse.data));
              info(`Session validation and player data fetch successful for: ${res.data.playerName}`, 'auth');
            } catch (playerFetchError) {
              warn(`Failed to fetch full player data during session validation: ${playerFetchError.message}`, 'auth');
            }
            
            info(`Session validation successful for: ${res.data.playerName}`, 'auth');
          } else {
            warn('Session validation failed - invalid response', 'auth');
            setAuthedPlayer('');
            setSessionId('');
            localStorage.removeItem('dw:shop:authedPlayer');
            localStorage.removeItem('dw:shop:sessionId');
          }
        } catch (err) {
          logApiError('App', 'POST', '/api/sessions/validate', err);
          error(`Session validation error: ${err.message}`, 'auth');
          setAuthedPlayer('');
          setSessionId('');
          localStorage.removeItem('dw:shop:authedPlayer');
          localStorage.removeItem('dw:shop:sessionId');
        }
      } else {
        debug('No session ID found for validation', 'auth');
      }
    }
    validate();
  }, [sessionId]);

  const handleKeyPress = (e) => {
    if (e.key === 'Enter') {
      handleLogin();
    }
  };

  const handleLogin = async () => {
    try {
      logUserAction('user', 'Login attempt', { username: loginName });
      const response = await axios.post('/api/players/login', { 
        name: loginName, 
        password: loginPw 
      });
      
      logApiCall('POST', '/api/players/login', { name: loginName }, response.status);
      
      if (response.data.sessionId && response.data.player) {
        // Update global state with session info and player data
        setAuthedPlayer(response.data.player.name);
        setSessionId(response.data.sessionId);
        localStorage.setItem('dw:shop:authedPlayer', JSON.stringify(response.data.player.name));
        localStorage.setItem('dw:shop:sessionId', JSON.stringify(response.data.sessionId));
        
        // Fetch full player data including tabInfo after successful login
        try {
          const fullPlayerResponse = await axios.get(`/api/players/${response.data.player.name}`, {
            headers: { 'x-session-id': response.data.sessionId }
          });
          localStorage.setItem('dw:shop:playerData', JSON.stringify(fullPlayerResponse.data));
          info(`Full player data loaded for: ${loginName}`, 'auth');
        } catch (playerFetchError) {
          warn(`Failed to fetch full player data: ${playerFetchError.message}`, 'auth');
          // Store minimal player data as fallback
          localStorage.setItem('dw:shop:playerData', JSON.stringify(response.data.player));
        }
        
        info(`Login successful for user: ${loginName}`, 'auth');
        logUserAction('user', 'Login successful', { username: loginName });
        setLoginMsg('Login successful!');
        setLoginName('');
        setLoginPw('');
        
        // Clear success message after 3 seconds
        setTimeout(() => setLoginMsg(''), 3000);
      } else {
        warn(`Login failed for user: ${loginName} - ${response.data.message || 'Unknown error'}`, 'auth');
        setLoginMsg(response.data.message || 'Login failed');
        
        // Clear error message after 5 seconds
        setTimeout(() => setLoginMsg(''), 5000);
      }
    } catch (err) {
      logApiError('App', 'POST', '/api/players/login', err);
      error(`Login error for user: ${loginName} - ${err.message}`, 'auth');
      setLoginMsg('Login failed. Please check your credentials and try again.');
      
      // Clear error message after 5 seconds
      setTimeout(() => setLoginMsg(''), 5000);
    }
  };

  async function handleLogout() {
    logUserAction('user', 'Logout attempt', { username: authedPlayer });
    if (sessionId) {
      try { 
        await axios.post('/api/sessions/logout', { sessionId }); 
        info(`Logout successful for user: ${authedPlayer}`, 'auth');
      } catch (err) {
        warn(`Logout API call failed: ${err.message}`, 'auth');
      }
    }
    setAuthedPlayer('');
    setSessionId('');
    localStorage.removeItem('dw:shop:authedPlayer');
    localStorage.removeItem('dw:shop:sessionId');
    setLoginMsg('Logged out successfully');
    info('User logged out successfully', 'auth');
    
    // Clear logout message after 3 seconds
    setTimeout(() => setLoginMsg(''), 3000);
  }

  // GM session is now handled through the regular login

  const [appBackgroundUrl, setAppBackgroundUrl] = useState(() => {
    try {
      return localStorage.getItem('dw:gmkit:background') || '/gmkit/deathwatch-banner.png';
    } catch (e) {
      return '/gmkit/deathwatch-banner.png';
    }
  });

  // On mount, try to get the gmkit list and pick a banner if available.
  useEffect(() => {
    let mounted = true;
    async function pickBackground() {
      try {
        const res = await axios.get('/api/gmkit/list');
        const list = Array.isArray(res.data) ? res.data : [];
        if (!mounted) return;
        // prefer explicit deathwatch-banner.png if present
        const banner = list.find(f => f.name === 'deathwatch-banner.png');
        if (banner) return setAppBackgroundUrl(banner.url);
        // otherwise use the first image-like file (png/jpg/jpeg)
        const firstImg = list.find(f => ['png', 'jpg', 'jpeg'].includes(f.ext));
        if (firstImg) return setAppBackgroundUrl(firstImg.url);
        // fallback remains the default (may 404) or no background
      } catch (err) {
        // ignore — keep default
        console.debug('Could not load gmkit list for background', err.message || err);
      }
    }
    pickBackground();
    return () => { mounted = false; };
  }, []);

  const appBackgroundStyle = {
    backgroundImage: `linear-gradient(rgba(2,6,23,0.75), rgba(15,23,42,0.75)), url('${appBackgroundUrl}')`,
    backgroundRepeat: 'no-repeat',
    backgroundPosition: 'left center, right center',
    backgroundSize: '25%, 25%',
    backgroundAttachment: 'fixed',
    backgroundBlendMode: 'multiply'
  };

  const navButtonClass = (active, accent = 'blue') => {
    const activeClass = accent === 'yellow'
      ? 'bg-yellow-600 text-white shadow-lg'
      : accent === 'purple'
        ? 'bg-purple-700 text-white shadow-lg'
        : 'bg-blue-600 text-white shadow-lg';
    return `mobile-nav-item rounded-lg font-medium transition-all ${active ? activeClass : 'bg-slate-700/50 text-slate-200 hover:bg-slate-600/50'}`;
  };

  return (
    <div className="App min-h-screen bg-gradient-to-br from-slate-900 via-slate-800 to-slate-900" style={tab === 'players' ? appBackgroundStyle : {}}>
      {/* Persistent Header */}
      <div className="sticky top-0 z-50 border-b border-slate-600 bg-slate-900/95 backdrop-blur-md">
        <div className="mx-auto max-w-6xl px-3 py-3 sm:px-6 sm:py-4">
          {/* Title and Login Row */}
          <div className="mb-3 flex flex-col justify-between gap-3 sm:flex-row sm:items-center">
            <h1 className="text-lg font-bold text-white sm:text-xl">Deathwatch Roller</h1>
            
            {/* Login Section */}
            <div className="min-w-0 flex-shrink-0">
              {authedPlayer ? (
                <div className="flex flex-wrap items-center gap-2 sm:gap-3">
                  <div className="flex min-w-0 items-center gap-2">
                    <div className="h-2 w-2 shrink-0 rounded-full bg-green-400"></div>
                    <span className="truncate text-sm font-medium text-white">Logged in as {authedPlayer}</span>
                  </div>
                  <button onClick={handleLogout} className="rounded-lg bg-red-600 px-3 py-1.5 text-sm font-medium text-white transition-colors hover:bg-red-500">
                    Logout
                  </button>
                  {loginMsg && <span className="rounded border border-green-500/30 bg-green-500/20 px-2 py-1 text-xs text-green-300">{loginMsg}</span>}
                </div>
              ) : (
                <div className="grid gap-2 sm:flex sm:flex-row">
                  <input
                    className="min-w-0 rounded-lg border border-slate-600 bg-slate-800 px-3 py-2 text-sm text-white placeholder-slate-400"
                    type="text"
                    placeholder="Username"
                    value={loginName}
                    onChange={e=>{setLoginName(e.target.value); setLoginPw(e.target.value==='gm'?'':'1234');}}
                    data-testid="login-user-input"
                  />
                  <input 
                    className="min-w-0 rounded-lg border border-slate-600 bg-slate-800 px-3 py-2 text-sm text-white placeholder-slate-400"
                    type="password" 
                    placeholder="Password (auto-filled)" 
                    value={loginPw} 
                    onChange={e=>setLoginPw(e.target.value)} 
                    onKeyPress={handleKeyPress}
                  />
                  <button onClick={handleLogin} className="rounded-lg bg-blue-600 px-4 py-2 text-sm font-medium text-white transition-colors hover:bg-blue-500">
                    Login
                  </button>
                  {loginMsg && <span className="rounded border border-red-500/30 bg-red-500/20 px-2 py-1 text-xs text-red-300">{loginMsg}</span>}
                </div>
              )}
            </div>
          </div>
          
          {/* Tab Navigation */}
          <div className="mobile-nav flex gap-1 overflow-x-auto pb-1 sm:flex-wrap sm:overflow-visible sm:pb-0">
            <button
              className={navButtonClass(tab === 'mission')}
              onClick={()=>{logUserAction('navigation', 'Tab switch', { from: tab, to: 'mission' }); setTab('mission')}}
            >
              Mission
            </button>
            <button
              className={navButtonClass(tab === 'roller')}
              onClick={()=>{logUserAction('navigation', 'Tab switch', { from: tab, to: 'roller' }); setTab('roller')}}
            >
              Dice Roller
            </button>
            <button
              className={navButtonClass(tab === 'shop')}
              onClick={()=>{logUserAction('navigation', 'Tab switch', { from: tab, to: 'shop' }); setTab('shop')}}
            >
              Requisition Shop
            </button>
            <button
              className={navButtonClass(tab === 'player')}
              onClick={()=>{logUserAction('navigation', 'Tab switch', { from: tab, to: 'player' }); setTab('player')}}
            >
              Character Sheet
            </button>
            <button
              className={navButtonClass(tab === 'rules')}
              onClick={()=>{logUserAction('navigation', 'Tab switch', { from: tab, to: 'rules' }); setTab('rules')}}
            >
              Rules
            </button>
            <button
              className={navButtonClass(tab === 'weapons')}
              onClick={()=>{logUserAction('navigation', 'Tab switch', { from: tab, to: 'weapons' }); setTab('weapons')}}
            >
              Weapons
            </button>
            <button
              className={navButtonClass(tab === 'battlemap')}
              onClick={()=>{logUserAction('navigation', 'Tab switch', { from: tab, to: 'battlemap' }); setTab('battlemap')}}
            >
              Battlemap
            </button>
            <a
              href="/cards.html"
              target="_blank"
              rel="noopener noreferrer"
              className="mobile-nav-item rounded-lg bg-slate-700/50 font-medium text-slate-200 transition-all hover:bg-slate-600/50"
            >
              🃏 Kort
            </a>
            <a
              href="/print.html"
              target="_blank"
              rel="noopener noreferrer"
              className="mobile-nav-item rounded-lg bg-slate-700/50 font-medium text-slate-200 transition-all hover:bg-slate-600/50"
            >
              🖨 Print
            </a>
            <button
              className={navButtonClass(tab === 'errors', 'yellow')}
              onClick={()=>{logUserAction('navigation', 'Tab switch', { from: tab, to: 'errors' }); setTab('errors')}}
            >
              ⚠ Error
            </button>
            {authedPlayer === 'gm' && (
              <>
                <button
                  className={navButtonClass(tab === 'mission')}
                  onClick={()=>{logUserAction('navigation', 'Tab switch', { from: tab, to: 'mission' }); setTab('mission')}}
                >
                  Mission
                </button>
                <button
                  className={navButtonClass(tab === 'bestiary')}
                  onClick={()=>{logUserAction('navigation', 'Tab switch', { from: tab, to: 'bestiary' }); setTab('bestiary')}}
                >
                  Bestiary
                </button>
                <button
                  className={navButtonClass(tab === 'players')}
                  onClick={()=>{logUserAction('navigation', 'Tab switch', { from: tab, to: 'players' }); setTab('players')}}
                >
                  Player Management
                </button>
                <button
                  className={navButtonClass(tab === 'gmkit')}
                  onClick={()=>{logUserAction('navigation', 'Tab switch', { from: tab, to: 'gmkit' }); setTab('gmkit')}}
                >
                  GM Kit
                </button>
                <button
                  className={navButtonClass(tab === 'simulation', 'purple')}
                  onClick={()=>{logUserAction('navigation', 'Tab switch', { from: tab, to: 'simulation' }); setTab('simulation')}}
                >
                  ⚙ Sim Lab
                </button>
              </>
            )}
          </div>
        </div>
      </div>
      
      {/* Main Content */}
      <div className="mx-auto max-w-6xl px-2 py-3 sm:px-6 sm:py-6">
        {/* User Info Card for easy access */}
        {!authedPlayer && (
          <div className="mb-6 p-4 rounded-lg bg-blue-900/20 border border-blue-500/30">
            <div className="flex items-center justify-between mb-2">
              <h3 className="text-sm font-semibold text-blue-300">Available Users</h3>
              <div className="flex items-center gap-2">
                <button onClick={fetchPlayers} className="text-xs px-2 py-1 rounded bg-slate-700/30 hover:bg-slate-700/50">Refresh</button>
              </div>
            </div>
            {playersError ? (
              <div className="text-xs text-red-400 mb-2">
                {playersError}
              </div>
            ) : null}
            <div className="flex flex-wrap gap-2 text-xs">
              {players && players.length > 0 ? players.map(player => (
                <button
                  key={player.name}
                  onClick={() => {setLoginName(player.name); setLoginPw(player.name==='gm'?'':'1234');}}
                  className="px-2 py-1 rounded bg-blue-700/30 text-blue-200 hover:bg-blue-600/40 transition-colors"
                >
                  {player.name}
                </button>
              )) : (
                <div className="text-xs text-blue-200/60">No users found. Click Refresh or check backend.</div>
              )}
            </div>
            <p className="text-xs text-blue-300/70 mt-2">Player password is auto-filled. GM password must be entered manually.</p>
          </div>
        )}
        
{tab==='roller' ? <DeathwatchRoller authedPlayer={authedPlayer} /> : tab==='shop' ? <RequisitionShop authedPlayer={authedPlayer} sessionId={sessionId} /> : tab==='rules' ? <RulesTab authedPlayer={authedPlayer} sessionId={sessionId} /> : tab==='weapons' ? <WeaponsTab /> : tab==='battlemap' ? <BattlemapTab authedPlayer={authedPlayer} sessionId={sessionId} /> : tab==='bestiary' ? (authedPlayer === 'gm' ? <BestiaryTab sessionId={sessionId} /> : <div className="p-6 rounded-lg bg-red-900/20 border border-red-500/30"><h2 className="text-xl font-bold text-red-300 mb-2">Access Denied</h2><p className="text-red-200">The Bestiary is only accessible to Game Masters. Please log in with a GM account.</p></div>) : tab==='players' ? <PlayerManagement authedPlayer={authedPlayer} sessionId={sessionId} /> : tab==='gmkit' ? <GMKit authedPlayer={authedPlayer} /> : tab==='simulation' ? <SimulationTab /> : tab==='errors' ? <ErrorReports authedPlayer={authedPlayer} sessionId={sessionId} /> : tab==='mission' ? <MissionTab authedPlayer={authedPlayer} /> : <PlayerTab
          authedPlayer={authedPlayer} 
          sessionId={sessionId}
        />}
      </div>
    </div>
  );
}

export default App;
