import { useState, useEffect, useCallback, useRef } from "react"
import "./App.css"

const API = window.location.hostname === "localhost" ? "http://localhost:8000" : ""

function App() {
  const [page, setPage] = useState("login")
  const [token, setToken] = useState(localStorage.getItem("access_token"))
  const [user, setUser] = useState(null)
  const [form, setForm] = useState({ username: "", email: "", password: "" })
  const [otp, setOtp] = useState("")
  const [msg, setMsg] = useState("")
  const hasCheckedAuth = useRef(false)

  const refreshAccessToken = useCallback(async () => {
    const refreshToken = localStorage.getItem("refresh_token")
    if (!refreshToken) { logout(); return null }
    try {
      const res = await fetch(`${API}/auth/refresh`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ refresh_token: refreshToken })
      })
      if (res.ok) {
        const data = await res.json()
        localStorage.setItem("access_token", data.access_token)
        localStorage.setItem("refresh_token", data.refresh_token)
        setToken(data.access_token)
        return data.access_token
      } else { logout(); return null }
    } catch { logout(); return null }
  }, [])

  const apiCall = useCallback(async (url, options = {}) => {
    let currentToken = localStorage.getItem("access_token")
    let res = await fetch(url, {
      ...options,
      headers: { "Content-Type": "application/json", ...options.headers, Authorization: `Bearer ${currentToken}` }
    })
    if (res.status === 401) {
      const newToken = await refreshAccessToken()
      if (newToken) {
        res = await fetch(url, {
          ...options,
          headers: { "Content-Type": "application/json", ...options.headers, Authorization: `Bearer ${newToken}` }
        })
      }
    }
    return res
  }, [refreshAccessToken])

  function navigateTo(newPage) {
    setPage(newPage)
    setMsg("")
    setOtp("")
  }

  function resetAll() {
    setPage("login")
    setMsg("")
    setOtp("")
    setForm({ username: "", email: "", password: "" })
  }

  useEffect(() => {
    if (!hasCheckedAuth.current) { hasCheckedAuth.current = true; if (token) getMe() }
  }, [])

  async function getMe() {
    const res = await apiCall(`${API}/me`)
    if (res.ok) { setUser(await res.json()); navigateTo("dashboard") }
    else logout()
  }

  async function register() {
    try {
      if (!/^[a-zA-Z0-9_]{3,20}$/.test(form.username)) { setMsg("Username: 3-20 chars, letters/numbers/_ only"); return }
      if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email)) { setMsg("Invalid email format"); return }
      if (form.password.length < 8) { setMsg("Password must be at least 8 characters"); return }
      const res = await fetch(`${API}/auth/register`, {
        method: "POST", headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ username: form.username, email: form.email, password: form.password })
      })
      const data = await res.json()
      if (res.ok) {
        setPage("verify-register")
        setOtp("")
        setMsg("OTP sent to your email. Enter it to verify.")
      } else {
        setMsg(data.detail || "Registration failed")
      }
    } catch (err) {
      setMsg("Network error. Is the backend running?")
    }
  }

  async function verifyRegister() {
    try {
      if (otp.length !== 6) { setMsg("Enter the 6-digit OTP"); return }
      const res = await fetch(`${API}/auth/verify-email`, {
        method: "POST", headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ email: form.email, code: otp })
      })
      const data = await res.json()
      if (res.ok) {
        setMsg("Account verified! Now login")
        navigateTo("login")
      } else {
        setMsg(data.detail || "Verification failed")
      }
    } catch (err) {
      setMsg("Network error. Is the backend running?")
    }
  }

  async function login() {
    try {
      const body = new URLSearchParams()
      body.append("username", form.username)
      body.append("password", form.password)
      const res = await fetch(`${API}/auth/login`, {
        method: "POST",
        headers: { "Content-Type": "application/x-www-form-urlencoded" },
        body: body.toString()
      })
      const data = await res.json()
      if (res.ok) {
        localStorage.setItem("access_token", data.access_token)
        localStorage.setItem("refresh_token", data.refresh_token)
        setToken(data.access_token)
        const meRes = await apiCall(`${API}/me`)
        if (meRes.ok) setUser(await meRes.json())
        navigateTo("dashboard")
      } else {
        setMsg(data.detail || "Login failed")
      }
    } catch (err) {
      setMsg("Network error. Is the backend running?")
    }
  }

  function logout() {
    localStorage.removeItem("access_token")
    localStorage.removeItem("refresh_token")
    setToken(null); setUser(null); resetAll()
  }

  async function forgotPassword() {
    try {
      if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email)) { setMsg("Enter a valid email"); return }
      const res = await fetch(`${API}/auth/forgot-password`, {
        method: "POST", headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ email: form.email })
      })
      const data = await res.json()
      if (res.ok) {
        setPage("verify-forgot")
        setOtp("")
        setMsg("OTP sent to your email")
      } else {
        setMsg(data.detail || "Failed to send OTP")
      }
    } catch (err) {
      setMsg("Network error. Is the backend running?")
    }
  }

  async function resetPassword() {
    try {
      if (otp.length !== 6) { setMsg("Enter the 6-digit OTP"); return }
      if (form.password.length < 8) { setMsg("Password must be at least 8 characters"); return }
      const res = await fetch(`${API}/auth/reset-password`, {
        method: "POST", headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ email: form.email, code: otp, new_password: form.password })
      })
      const data = await res.json()
      if (res.ok) {
        setMsg("Password reset successful!")
        navigateTo("login")
      } else {
        setMsg(data.detail || "Reset failed")
      }
    } catch (err) {
      setMsg("Network error. Is the backend running?")
    }
  }

  return (
    <div className="container">
      {page === "login" && (
        <div className="card">
          <h2>Login</h2>
          {msg && <p className="msg">{msg}</p>}
          <input placeholder="Username or Email" value={form.username} onChange={e => setForm({ ...form, username: e.target.value })} />
          <input type="password" placeholder="Password" value={form.password} onChange={e => setForm({ ...form, password: e.target.value })} />
          <button onClick={login}>Login</button>
          <p className="link" onClick={() => navigateTo("register")}>No account? Register</p>
          <p className="link" onClick={() => navigateTo("forgot-password")}>Forgot password?</p>
        </div>
      )}

      {page === "register" && (
        <div className="card">
          <h2>Register</h2>
          {msg && <p className="msg">{msg}</p>}
          <input placeholder="Username" value={form.username} onChange={e => setForm({ ...form, username: e.target.value })} />
          <input type="email" placeholder="Email" value={form.email} onChange={e => setForm({ ...form, email: e.target.value })} />
          <input type="password" placeholder="Password (min 8 chars)" value={form.password} onChange={e => setForm({ ...form, password: e.target.value })} />
          <button onClick={register}>Register</button>
          <p className="link" onClick={() => navigateTo("login")}>Have account? Login</p>
        </div>
      )}

      {page === "verify-register" && (
        <div className="card">
          <h2>Verify Account</h2>
          {msg && <p className="msg">{msg}</p>}
          <p className="info">OTP sent to: {form.email || "your email"}</p>
          <input placeholder="Enter 6-digit OTP" value={otp} onChange={e => setOtp(e.target.value)} />
          <button onClick={verifyRegister}>Verify</button>
        </div>
      )}

      {page === "forgot-password" && (
        <div className="card">
          <h2>Forgot Password</h2>
          {msg && <p className="msg">{msg}</p>}
          <input type="email" placeholder="Email" value={form.email} onChange={e => setForm({ ...form, email: e.target.value })} />
          <button onClick={forgotPassword}>Send OTP</button>
          <p className="link" onClick={() => navigateTo("login")}>Back to Login</p>
        </div>
      )}

      {page === "verify-forgot" && (
        <div className="card">
          <h2>Reset Password</h2>
          {msg && <p className="msg">{msg}</p>}
          <p className="info">OTP sent to: {form.email || "your email"}</p>
          <input placeholder="Enter 6-digit OTP" value={otp} onChange={e => setOtp(e.target.value)} />
          <input type="password" placeholder="New Password (min 8 chars)" value={form.password} onChange={e => setForm({ ...form, password: e.target.value })} />
          <button onClick={resetPassword}>Reset Password</button>
          <p className="link" onClick={() => navigateTo("forgot-password")}>Back</p>
        </div>
      )}

      {page === "dashboard" && (
        <div className="card">
          <h2>Dashboard</h2>
          <p>ID: {user?.id}</p>
          <p>Username: {user?.username}</p>
          <p>Email: {user?.email}</p>
          <button onClick={logout}>Logout</button>
        </div>
      )}
    </div>
  )
}

export default App
