import React, { useEffect, useMemo, useState } from "react";
import { createRoot } from "react-dom/client";
import { BarChart3, CalendarDays, Crown, Gauge, LogOut, Map, Shield, Ticket, Wand2 } from "lucide-react";
import "./styles.css";

type User = { id: string; email: string; name: string; role: "USER" | "ADMIN" };
type Race = {
  id: number;
  raceNumber: number;
  raceName: string;
  distanceMeters: number;
  conditionDisplay: string;
  analysisStatus: string;
  raceDay: { raceDate: string; trackName: string };
  entries: Array<{ id: number; saddleclothNumber: number; carriedWeight: number; jockeyName: string; trainerName: string; horse: { horseName: string } }>;
};
type AnalysisRow = {
  horseId: number;
  number: number | string;
  horseName: string;
  trainerName: string;
  jockeyName: string;
  oddsText: string;
  style: string;
  avgSpeed: number;
  avgPace: number;
  totalScore: number;
  note: string;
};
type RaceAnalysis = {
  paceShape: string;
  summary: string;
  rankings: AnalysisRow[];
  race: { id: number; raceNumber: number; conditionDisplay: string; distanceMeters: number };
};

const apiBase = import.meta.env.VITE_API_URL || "";

async function api(path: string, options: RequestInit = {}) {
  const response = await fetch(`${apiBase}${path}`, {
    credentials: "include",
    headers: { "Content-Type": "application/json", ...(options.headers || {}) },
    ...options
  });
  const data = await response.json().catch(() => ({}));
  if (!response.ok || data.ok === false) throw new Error(data.error || `Request failed ${response.status}`);
  return data;
}

function money(value: number) {
  return Number(value || 0).toLocaleString(undefined, { style: "currency", currency: "JMD" });
}

function App() {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    api("/api/auth/me").then(data => setUser(data.user)).catch(() => setUser(null)).finally(() => setLoading(false));
  }, []);

  if (loading) return <Splash title="Loading" text="Connecting to Caymanas Analyzer..." />;
  if (!user) return <AuthScreen onUser={setUser} />;
  return <Shell user={user} onLogout={() => setUser(null)} />;
}

function Splash({ title, text }: { title: string; text: string }) {
  return <main className="center-screen"><section className="hero-panel"><p className="eyebrow">{title}</p><h1>{text}</h1></section></main>;
}

function AuthScreen({ onUser }: { onUser: (user: User) => void }) {
  const [mode, setMode] = useState<"login" | "register">("login");
  const [error, setError] = useState("");

  async function submit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setError("");
    const form = Object.fromEntries(new FormData(event.currentTarget).entries());
    try {
      const data = await api(`/api/auth/${mode}`, { method: "POST", body: JSON.stringify(form) });
      onUser(data.user);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Login failed");
    }
  }

  return (
    <main className="auth-page">
      <section className="brand-panel">
        <p className="eyebrow">Caymanas Analyzer</p>
        <h1>Commercial race intelligence for serious players.</h1>
        <p>Admin controls the race data. Users analyze available races, build tickets, and track their own bankroll.</p>
      </section>
      <form className="auth-card" onSubmit={submit}>
        <div className="segmented">
          <button type="button" className={mode === "login" ? "active" : ""} onClick={() => setMode("login")}>Login</button>
          <button type="button" className={mode === "register" ? "active" : ""} onClick={() => setMode("register")}>Register</button>
        </div>
        {mode === "register" && <label>Name<input name="name" autoComplete="name" required /></label>}
        <label>Email<input name="email" type="email" autoComplete="email" required /></label>
        <label>Password<input name="password" type="password" autoComplete={mode === "login" ? "current-password" : "new-password"} minLength={8} required /></label>
        {error && <p className="error-text">{error}</p>}
        <button className="primary-btn">{mode === "login" ? "Login" : "Create Account"}</button>
        <p className="fine-print">The first registered account becomes admin.</p>
      </form>
    </main>
  );
}

function Shell({ user, onLogout }: { user: User; onLogout: () => void }) {
  const [tab, setTab] = useState(user.role === "ADMIN" ? "admin" : "races");

  async function logout() {
    await api("/api/auth/logout", { method: "POST" }).catch(() => null);
    onLogout();
  }

  const nav = [
    { id: "races", label: "Races", icon: CalendarDays },
    { id: "analysis", label: "Analysis", icon: Wand2 },
    { id: "bets", label: "Bets", icon: Ticket },
    { id: "roi", label: "ROI", icon: BarChart3 },
    { id: "admin", label: "Admin", icon: Shield, admin: true }
  ].filter(item => !item.admin || user.role === "ADMIN");

  return (
    <div className="app">
      <aside className="sidebar">
        <div className="logo"><Crown size={22} /><span>Caymanas</span></div>
        <nav>
          {nav.map(item => <button key={item.id} className={tab === item.id ? "active" : ""} onClick={() => setTab(item.id)}><item.icon size={18} />{item.label}</button>)}
        </nav>
        <button className="logout" onClick={logout}><LogOut size={18} />Logout</button>
      </aside>
      <main className="content">
        <header className="page-head">
          <div><p className="eyebrow">{user.role}</p><h1>{tab === "admin" ? "Admin Control Center" : "Race Day Workspace"}</h1></div>
          <span className="user-pill">{user.name}</span>
        </header>
        {tab === "races" && <RaceList />}
        {tab === "analysis" && <AnalysisView />}
        {tab === "bets" && <BetBuilder />}
        {tab === "roi" && <RoiDashboard />}
        {tab === "admin" && user.role === "ADMIN" && <AdminPanel />}
      </main>
    </div>
  );
}

function RaceList() {
  const [races, setRaces] = useState<Race[]>([]);
  const [error, setError] = useState("");
  useEffect(() => { api("/api/races").then(data => setRaces(data.races)).catch(err => setError(err.message)); }, []);
  return <section className="panel"><h2>Race Cards</h2>{error && <p className="error-text">{error}</p>}<div className="race-grid">{races.map(race => <RaceCard key={race.id} race={race} />)}</div></section>;
}

function RaceCard({ race }: { race: Race }) {
  const locked = !race.entries.length;
  return (
    <article className="race-card">
      <div className="row-between"><strong>Race {race.raceNumber}</strong><span className={locked ? "status locked" : "status"}>{locked ? "NO ENTRIES" : "READY"}</span></div>
      <p>{race.conditionDisplay || race.raceName || "Condition pending"}</p>
      <p className="muted">{new Date(race.raceDay.raceDate).toLocaleDateString()} | {race.distanceMeters}m | {race.entries.length} entries</p>
      <div className="mini-list">{race.entries.slice(0, 4).map(e => <span key={e.id}>#{e.saddleclothNumber} {e.horse.horseName}</span>)}</div>
      {locked ? <p className="muted">Add/import entries before analysis.</p> : <p className="muted">Open Analysis to calculate rankings from imported data.</p>}
    </article>
  );
}

function AnalysisView() {
  const [races, setRaces] = useState<Race[]>([]);
  const [raceId, setRaceId] = useState("");
  const [analysis, setAnalysis] = useState<RaceAnalysis | null>(null);
  const [error, setError] = useState("");
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    api("/api/races").then(data => {
      const list = data.races || [];
      setRaces(list);
      if (list[0]) setRaceId(String(list[0].id));
    }).catch(err => setError(err.message));
  }, []);

  async function runAnalysis(event?: React.FormEvent) {
    event?.preventDefault();
    if (!raceId) return;
    setError("");
    setLoading(true);
    try {
      const data = await api(`/api/races/${raceId}/analysis`);
      setAnalysis(data.analysis);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Analysis failed");
    } finally {
      setLoading(false);
    }
  }

  return (
    <section className="analysis-layout">
      <form className="panel analysis-controls" onSubmit={runAnalysis}>
        <h2>Run Race Analysis</h2>
        <label>Race<select value={raceId} onChange={event => setRaceId(event.target.value)}>
          {races.map(race => <option key={race.id} value={race.id}>{new Date(race.raceDay.raceDate).toLocaleDateString()} | Race {race.raceNumber} | {race.conditionDisplay || race.raceName}</option>)}
        </select></label>
        <button className="primary-btn" disabled={!raceId || loading}>{loading ? "Running..." : "Run Analysis"}</button>
        {error && <p className="error-text">{error}</p>}
      </form>
      {analysis && <section className="panel">
        <div className="row-between"><h2>Race {analysis.race.raceNumber} Rankings</h2><span className="status">{analysis.paceShape}</span></div>
        <pre className="analysis-summary">{analysis.summary}</pre>
        <div className="table-wrap"><table>
          <thead><tr><th>Rank</th><th>No.</th><th>Horse</th><th>Score</th><th>Style</th><th>ML</th><th>Speed</th><th>Pace</th><th>Jockey</th><th>Trainer</th><th>Note</th></tr></thead>
          <tbody>{analysis.rankings.map((row, index) => <tr key={row.horseId}>
            <td>{index + 1}</td><td>{row.number}</td><td>{row.horseName}</td><td>{row.totalScore}</td><td>{row.style}</td><td>{row.oddsText}</td><td>{row.avgSpeed}</td><td>{row.avgPace}</td><td>{row.jockeyName}</td><td>{row.trainerName}</td><td>{row.note}</td>
          </tr>)}</tbody>
        </table></div>
      </section>}
      {!analysis && <section className="tool-grid">
        <ToolCard icon={<Wand2 />} title="AI Analysis" text="Select a race and run analysis from imported entries, PP, workouts, and odds." />
        <ToolCard icon={<Map />} title="Pace Map" text="Pace shape is calculated from EP/LP and running style data." />
        <ToolCard icon={<Gauge />} title="Monte Carlo" text="Simulation view can be added after the base rankings are visible." />
        <ToolCard icon={<Ticket />} title="Live Assistance" text="Use rankings and imported odds as live race guidance." />
      </section>}
    </section>
  );
}

function BetBuilder() {
  const [races, setRaces] = useState<Race[]>([]);
  const [raceId, setRaceId] = useState("");
  const [analysis, setAnalysis] = useState<RaceAnalysis | null>(null);
  const [message, setMessage] = useState("");
  useEffect(() => {
    api("/api/races").then(data => {
      const list = data.races || [];
      setRaces(list);
      if (list[0]) setRaceId(String(list[0].id));
    }).catch(() => null);
  }, []);
  async function build() {
    if (!raceId) return;
    const data = await api(`/api/races/${raceId}/analysis`);
    setAnalysis(data.analysis);
  }
  async function saveWinTicket(row: AnalysisRow) {
    if (!raceId) return;
    await api("/api/tickets", {
      method: "POST",
      body: JSON.stringify({
        raceId: Number(raceId),
        betType: "Win",
        unitStake: 100,
        totalCost: 100,
        ticketText: `#${row.number} ${row.horseName}`,
        notes: `PWA analysis score ${row.totalScore}. ${row.note}`
      })
    });
    setMessage(`Saved win ticket for ${row.horseName}.`);
  }
  return <section className="panel"><h2>Bet Builder</h2>
    <div className="inline-form"><select value={raceId} onChange={event => setRaceId(event.target.value)}>{races.map(race => <option key={race.id} value={race.id}>Race {race.raceNumber} | {race.conditionDisplay || race.raceName}</option>)}</select><button className="primary-btn" onClick={build}>Build From Analysis</button></div>
    {message && <p className="success-text">{message}</p>}
    {analysis ? <div className="ticket-list">{analysis.rankings.slice(0, 4).map(row => <article key={row.horseId} className="ticket-card"><strong>#{row.number} {row.horseName}</strong><span>Score {row.totalScore} | ML {row.oddsText || "-"}</span><button onClick={() => saveWinTicket(row)}>Save Win Ticket</button></article>)}</div> : <p className="muted">Run this to build simple tickets from the actual imported race analysis.</p>}
  </section>;
}

function RoiDashboard() {
  const [data, setData] = useState<any>(null);
  useEffect(() => { api("/api/tickets/roi").then(setData).catch(() => null); }, []);
  const roi = data?.roi || {};
  return <section className="metric-grid"><Metric label="Tickets" value={roi.tickets || 0} /><Metric label="Stake" value={money(roi.stake)} /><Metric label="Return" value={money(roi.returns)} /><Metric label="ROI" value={`${Number(roi.roiPct || 0).toFixed(1)}%`} /></section>;
}

function AdminPanel() {
  return (
    <section className="admin-grid">
      <AdminRaceDayForm />
      <section className="panel"><h2>Admin Rules</h2><p className="muted">Only admins can create race days, races, entries, PP, and results. Users can analyze only when status is Analysis Available.</p></section>
    </section>
  );
}

function AdminRaceDayForm() {
  const [message, setMessage] = useState("");
  async function submit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const form = Object.fromEntries(new FormData(event.currentTarget).entries());
    await api("/api/races/admin/race-days", { method: "POST", body: JSON.stringify(form) });
    setMessage("Race day saved.");
    event.currentTarget.reset();
  }
  return <form className="panel form" onSubmit={submit}><h2>Create Race Day</h2><label>Date<input name="raceDate" type="date" required /></label><label>Track<input name="trackName" defaultValue="Caymanas Park" /></label><label>Weather<textarea name="weatherNotes" /></label><button className="primary-btn">Save</button>{message && <p className="success-text">{message}</p>}</form>;
}

function ToolCard({ icon, title, text }: { icon: React.ReactNode; title: string; text: string }) {
  return <article className="tool-card">{icon}<h2>{title}</h2><p>{text}</p></article>;
}

function Metric({ label, value }: { label: string; value: React.ReactNode }) {
  return <article className="metric"><span>{label}</span><strong>{value}</strong></article>;
}

createRoot(document.getElementById("root")!).render(<App />);
