import { useEffect, useMemo, useState } from "react";
import { AnimatePresence, motion } from "framer-motion";
import toast, { Toaster } from "react-hot-toast";
import SearchRoomsPage from "./pages/SearchRoomsPage.jsx";
import CreateReservationPage from "./pages/CreateReservationPage.jsx";
import ApprovalsPage from "./pages/ApprovalsPage.jsx";
import ReportsPage from "./pages/ReportsPage.jsx";
import AdminPanelPage from "./pages/AdminPanelPage.jsx";
import {
  Activity,
  ArrowRight,
  BarChart3,
  Boxes,
  CalendarCheck,
  CheckCircle2,
  ClipboardCheck,
  Database,
  DoorOpen,
  LogOut,
  PlusCircle,
  Search,
  ShieldCheck,
  Sparkles,
  UserRound,
  Users,
} from "lucide-react";

import {
  getDashboardStats,
  getHealth,
  loginUser,
  registerUser,
} from "./api.js";

function App() {
  const [activeUser, setActiveUser] = useState(() => {
    try {
      const savedUser = localStorage.getItem("activeUser");
      return savedUser ? JSON.parse(savedUser) : null;
    } catch {
      localStorage.removeItem("activeUser");
      return null;
    }
  });

  const [authView, setAuthView] = useState(() => {
    return localStorage.getItem("authView") || "landing";
  });

  const [activePage, setActivePage] = useState(() => {
    return localStorage.getItem("activePage") || "dashboard";
  });

  function changeAuthView(view) {
    localStorage.setItem("authView", view);
    setAuthView(view);
  }

  function handleLogin(user) {
    localStorage.setItem("activeUser", JSON.stringify(user));
    localStorage.setItem("activePage", "dashboard");
    localStorage.removeItem("authView");

    setActiveUser(user);
    setActivePage("dashboard");

    toast.success(`Logged in as ${user.fullName}`);
  }

  function handleLogout() {
    localStorage.removeItem("activeUser");
    localStorage.removeItem("activePage");
    localStorage.setItem("authView", "landing");

    setActiveUser(null);
    setAuthView("landing");
    setActivePage("dashboard");
  }

  useEffect(() => {
    if (activeUser) {
      localStorage.setItem("activePage", activePage);
    }
  }, [activePage, activeUser]);

  if (!activeUser) {
    return (
        <>
          <Toaster position="top-right" />
          <AnimatePresence mode="wait">
            {authView === "landing" && (
                <PageMotion key="landing">
                  <LandingScreen
                      onLoginClick={() => changeAuthView("login")}
                      onRegisterClick={() => changeAuthView("register")}
                  />
                </PageMotion>
            )}

            {authView === "login" && (
                <PageMotion key="login">
                  <LoginScreen
                      onLogin={handleLogin}
                      onBack={() => changeAuthView("landing")}
                      onRegisterClick={() => changeAuthView("register")}
                  />
                </PageMotion>
            )}

            {authView === "register" && (
                <PageMotion key="register">
                  <RegisterScreen
                      onBack={() => changeAuthView("landing")}
                      onLoginClick={() => changeAuthView("login")}
                      onRegistered={handleLogin}
                  />
                </PageMotion>
            )}
          </AnimatePresence>
        </>
    );
  }

  return (
      <>
        <Toaster position="top-right" />
        <AppShell
            activeUser={activeUser}
            activePage={activePage}
            setActivePage={setActivePage}
            onLogout={handleLogout}
        >
          <AnimatePresence mode="wait">
            {activePage === "dashboard" && (
                <PageMotion key="dashboard">
                  <Dashboard activeUser={activeUser} setActivePage={setActivePage} />
                </PageMotion>
            )}

            {activePage === "search" && (
                <PageMotion key="search">
                  <SearchRoomsPage />
                </PageMotion>
            )}

            {activePage === "create" && (
                <PageMotion key="create">
                  <CreateReservationPage activeUser={activeUser} />
                </PageMotion>
            )}

            {activePage === "approvals" && (
                <PageMotion key="approvals">
                  <ApprovalsPage activeUser={activeUser} />
                </PageMotion>
            )}

            {activePage === "reports" && (
                <PageMotion key="reports">
                  <ReportsPage />
                </PageMotion>
            )}

            {activePage === "admin" && (
                <PageMotion key="admin">
                  <AdminPanelPage activeUser={activeUser} />
                </PageMotion>
            )}
          </AnimatePresence>
        </AppShell>
      </>
  );
}

function LandingScreen({ onLoginClick, onRegisterClick }) {
  return (
      <div className="landing-page">
        <div className="landing-orb orb-one" />
        <div className="landing-orb orb-two" />
        <div className="landing-orb orb-three" />

        <header className="landing-header">
          <button
              className="landing-brand logo-home-button"
              type="button"
              onClick={() => window.scrollTo({ top: 0, behavior: "smooth" })}
              title="Go to home"
          >
            <img src="/logo.png" alt="Room Reservation logo" />
          </button>

          <div className="landing-header-actions">
            <button className="ghost-button" onClick={onLoginClick}>
              Sign in
            </button>
            <button className="landing-small-primary" onClick={onRegisterClick}>
              Create account
            </button>
          </div>
        </header>

        <main className="landing-main">
          <motion.div
              className="landing-hero-content"
              initial={{ opacity: 0, y: 26 }}
              animate={{ opacity: 1, y: 0 }}
              transition={{ duration: 0.55 }}
          >
            <div className="landing-eyebrow">
              <Sparkles size={16} />
              Room Management Platform
            </div>

            <h1>Smart Room Reservation System</h1>

            <p>
              Search available rooms, create reservation requests, manage approvals,
              and monitor resource usage through live PostgreSQL reports.
            </p>

            <div className="landing-actions">
              <button className="landing-primary" onClick={onLoginClick}>
                Sign in
                <ArrowRight size={20} />
              </button>

              <button className="landing-secondary" onClick={onRegisterClick}>
                Create account
                <UserRound size={19} />
              </button>
            </div>
          </motion.div>

          <motion.div
              className="landing-preview-card"
              initial={{ opacity: 0, x: 36, scale: 0.96 }}
              animate={{ opacity: 1, x: 0, scale: 1 }}
              transition={{ duration: 0.65, delay: 0.15 }}
          >
            <div className="preview-topbar">
              <span />
              <span />
              <span />
            </div>

            <div className="preview-header">
              <div>
                <span>Live dashboard</span>
                <h3>Reservation Control Center</h3>
              </div>

              <div className="preview-live">
                <span className="status-dot" />
                Online
              </div>
            </div>

            <div className="preview-stats">
              <div>
                <DoorOpen size={22} />
                <strong>Rooms</strong>
                <span>Availability search</span>
              </div>
              <div>
                <ClipboardCheck size={22} />
                <strong>Approvals</strong>
                <span>Role-based decisions</span>
              </div>
              <div>
                <BarChart3 size={22} />
                <strong>Reports</strong>
                <span>Advanced analytics</span>
              </div>
            </div>

            <div className="preview-flow">
              <div className="flow-item">
                <CheckCircle2 size={18} />
                Search available rooms
              </div>
              <div className="flow-item">
                <CheckCircle2 size={18} />
                Create pending reservation
              </div>
              <div className="flow-item">
                <CheckCircle2 size={18} />
                Approve through stored function
              </div>
            </div>
          </motion.div>
        </main>
      </div>
  );
}

function LoginScreen({ onLogin, onBack, onRegisterClick }) {
  const [form, setForm] = useState({
    identifier: "",
    password: "",
  });

  const [loading, setLoading] = useState(false);

  function updateField(field, value) {
    setForm((prev) => ({ ...prev, [field]: value }));
  }

  async function submit(e) {
    e.preventDefault();

    if (!form.identifier.trim()) {
      toast.error("Username or email is required.");
      return;
    }

    if (!form.password.trim()) {
      toast.error("Password is required.");
      return;
    }

    setLoading(true);

    try {
      const user = await loginUser({
        identifier: form.identifier,
        password: form.password,
      });

      onLogin(user);
    } catch (err) {
      toast.error(err.message);
    } finally {
      setLoading(false);
    }
  }

  return (
      <div className="auth-page">
        <div className="landing-orb orb-one" />
        <div className="landing-orb orb-two" />
        <div className="landing-orb orb-three" />

        <motion.div
            className="auth-card"
            initial={{ opacity: 0, y: 28, scale: 0.96 }}
            animate={{ opacity: 1, y: 0, scale: 1 }}
            transition={{ duration: 0.55, ease: "easeOut" }}
        >
          <button className="auth-back-button" onClick={onBack}>
            ← Back to home
          </button>

          <div className="auth-left-panel">
            <button
                className="auth-logo logo-home-button"
                type="button"
                onClick={onBack}
                title="Back to home"
            >
              <img src="/logo.png" alt="Room Reservation logo" />
            </button>

            <div className="auth-left-copy">
              <div className="landing-eyebrow">
                <ShieldCheck size={16} />
                Role-based access
              </div>

              <h2>Access the reservation workspace.</h2>
              <p>
                Continue to the reservation system with the permissions assigned
                to your user role. Manage reservations, approvals, reports and
                administrative modules.
              </p>
            </div>
          </div>

          <div className="auth-right-panel">
            <form className="login-form polished" onSubmit={submit}>
              <div className="auth-form-header">
                <div className="auth-icon-badge">
                  <UserRound size={24} />
                </div>

                <div>
                  <h1>Sign In</h1>
                  <p>Enter your account details and continue with role-based access.</p>
                </div>
              </div>

              <label>
                Username or email
                <input
                    value={form.identifier}
                    onChange={(e) => updateField("identifier", e.target.value)}
                    placeholder="Enter username or email"
                    autoComplete="username"
                />
              </label>

              <label>
                Password
                <input
                    type="password"
                    value={form.password}
                    onChange={(e) => updateField("password", e.target.value)}
                    placeholder="Enter your password"
                    autoComplete="current-password"
                />
              </label>

              <button className="primary full auth-submit" disabled={loading}>
                {loading ? "Signing in..." : "Sign in"}
                <ArrowRight size={18} />
              </button>

              <button className="auth-link-button" type="button" onClick={onRegisterClick}>
                Create account
              </button>
            </form>
          </div>
        </motion.div>
      </div>
  );
}

function RegisterScreen({ onBack, onLoginClick, onRegistered }) {
  const [form, setForm] = useState({
    fullName: "",
    email: "",
    username: "",
    password: "",
    confirmPassword: "",
  });

  const [loading, setLoading] = useState(false);

  function updateField(field, value) {
    setForm((prev) => ({
      ...prev,
      [field]: value,
    }));
  }

  async function submit(e) {
    e.preventDefault();

    if (!form.fullName.trim()) {
      toast.error("Full name is required.");
      return;
    }

    if (!form.email.trim()) {
      toast.error("Email is required.");
      return;
    }

    if (!form.username.trim()) {
      toast.error("Username is required.");
      return;
    }

    if (!form.password.trim()) {
      toast.error("Password is required.");
      return;
    }

    if (form.password.length < 8) {
      toast.error("Password must contain at least 8 characters.");
      return;
    }

    if (form.password !== form.confirmPassword) {
      toast.error("Passwords do not match.");
      return;
    }

    setLoading(true);

    try {
      const user = await registerUser({
        fullName: form.fullName.trim(),
        email: form.email.trim(),
        username: form.username.trim(),
        password: form.password,
      });

      toast.success("Account created successfully.");
      onRegistered(user);
    } catch (err) {
      toast.error(err.message);
    } finally {
      setLoading(false);
    }
  }

  return (
      <div className="register-page">
        <div className="landing-orb orb-one" />
        <div className="landing-orb orb-two" />
        <div className="landing-orb orb-three" />

        <motion.div
            className="register-card"
            initial={{ opacity: 0, y: 28, scale: 0.96 }}
            animate={{ opacity: 1, y: 0, scale: 1 }}
            transition={{ duration: 0.5, ease: "easeOut" }}
        >
          <button className="auth-back-button" type="button" onClick={onBack}>
            ← Back to home
          </button>

          <div className="register-left">
            <button
                className="register-logo-button logo-home-button"
                type="button"
                onClick={onBack}
                title="Back to home"
            >
              <img src="/logo.png" alt="Room Reservation logo" />
            </button>

            <div>
              <div className="landing-eyebrow">
                <UserRound size={16} />
                Account creation
              </div>

              <h1>Create your account</h1>

              <p>
                Create a standard user account to submit room and equipment reservation requests.
                Administrative permissions are assigned separately by the system administrator.
              </p>
            </div>
          </div>

          <form className="register-form" onSubmit={submit}>
            <label>
              Full name
              <input
                  value={form.fullName}
                  onChange={(e) => updateField("fullName", e.target.value)}
                  placeholder="Enter your full name"
                  autoComplete="name"
              />
            </label>

            <label>
              Email
              <input
                  type="email"
                  value={form.email}
                  onChange={(e) => updateField("email", e.target.value)}
                  placeholder="example@finki.ukim.mk"
                  autoComplete="email"
              />
            </label>

            <label>
              Username
              <input
                  value={form.username}
                  onChange={(e) => updateField("username", e.target.value)}
                  placeholder="example_user"
                  autoComplete="username"
              />
            </label>

            <label>
              Password
              <input
                  type="password"
                  value={form.password}
                  onChange={(e) => updateField("password", e.target.value)}
                  placeholder="At least 8 characters"
                  autoComplete="new-password"
              />
            </label>

            <label>
              Confirm password
              <input
                  type="password"
                  value={form.confirmPassword}
                  onChange={(e) => updateField("confirmPassword", e.target.value)}
                  placeholder="Repeat password"
                  autoComplete="new-password"
              />
            </label>

            <button className="landing-primary full" type="submit" disabled={loading}>
              {loading ? "Creating account..." : "Create account"}
              <ArrowRight size={19} />
            </button>

            <button className="auth-link-button" type="button" onClick={onLoginClick}>
              Already have an account? Sign in
            </button>
          </form>
        </motion.div>
      </div>
  );
}

function AppShell({ activeUser, activePage, setActivePage, onLogout, children }) {
  const items = useMemo(() => {
    const base = [
      { key: "dashboard", label: "Dashboard", icon: Activity, roles: ["regular", "approver", "admin"] },
      { key: "search", label: "Search Rooms", icon: Search, roles: ["regular", "approver", "admin"] },
      { key: "create", label: "Create Reservation", icon: PlusCircle, roles: ["regular", "approver", "admin"] },
      { key: "approvals", label: "Approvals", icon: ClipboardCheck, roles: ["approver", "admin"] },
      { key: "reports", label: "Reports", icon: BarChart3, roles: ["regular", "approver", "admin"] },
      { key: "admin", label: "Admin Panel", icon: ShieldCheck, roles: ["admin"] },
    ];

    return base.filter((item) => item.roles.includes(activeUser.role));
  }, [activeUser.role]);

  const activeItem = items.find((item) => item.key === activePage);

  useEffect(() => {
    const pageIsAllowed = items.some((item) => item.key === activePage);

    if (!pageIsAllowed) {
      localStorage.setItem("activePage", "dashboard");
      setActivePage("dashboard");
    }
  }, [items, activePage, setActivePage]);

  return (
      <div className="app-shell">
        <aside className="sidebar">
          <button
              className="brand brand-only-logo logo-home-button"
              type="button"
              onClick={() => setActivePage("dashboard")}
              title="Go to dashboard"
          >
            <div className="brand-logo">
              <img src="/logo.png" alt="Room Reservation logo" />
            </div>
          </button>

          <nav className="nav-menu">
            {items.map((item) => {
              const Icon = item.icon;

              return (
                  <button
                      key={item.key}
                      className={activePage === item.key ? "active" : ""}
                      onClick={() => setActivePage(item.key)}
                  >
                    <Icon size={19} />
                    <span>{item.label}</span>
                  </button>
              );
            })}
          </nav>

          <div className="sidebar-footer">
            <div className="user-card">
              <div className="avatar small">{getInitials(activeUser.fullName)}</div>

              <div>
                <strong>{activeUser.fullName}</strong>
                <span>{activeUser.role}</span>
              </div>

              <button className="icon-button" onClick={onLogout} title="Logout">
                <LogOut size={17} />
              </button>
            </div>
          </div>
        </aside>

        <main className="main-area">
          <header className="topbar">
            <div>
              <h2>{activeItem?.label || "Room Reservation"}</h2>
            </div>

            <div className="topbar-actions">
              <div className="status-pill">
                <span className="status-dot" />
                Live database
              </div>

              <div className="top-user">
                <UserRound size={18} />
                <div>
                  <strong>{activeUser.fullName}</strong>
                  <span>{activeUser.role}</span>
                </div>
              </div>
            </div>
          </header>

          {children}
        </main>
      </div>
  );
}

function Dashboard({ activeUser, setActivePage }) {
  const [stats, setStats] = useState(null);
  const [databaseOnline, setDatabaseOnline] = useState(false);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    let mounted = true;

    async function loadDashboard() {
      setLoading(true);

      try {
        const [statsResponse, healthResponse] = await Promise.all([
          getDashboardStats(),
          getHealth().catch(() => null),
        ]);

        if (!mounted) {
          return;
        }

        setStats(statsResponse);
        setDatabaseOnline(Boolean(healthResponse));
      } catch (err) {
        if (!mounted) {
          return;
        }

        setDatabaseOnline(false);
        toast.error(err.message || "Dashboard data could not be loaded.");
      } finally {
        if (mounted) {
          setLoading(false);
        }
      }
    }

    loadDashboard();

    return () => {
      mounted = false;
    };
  }, []);

  const safeStats = stats || {
    totalRooms: 0,
    totalEquipmentTypes: 0,
    totalUsers: 0,
    pendingReservations: 0,
    approvedReservations: 0,
  };

  const firstName = activeUser?.fullName?.split(" ")?.[0] || "User";
  const role = activeUser?.role || "regular";

  const statCards = [
    {
      label: "Rooms",
      value: safeStats.totalRooms,
      meta: "Available spaces",
      icon: DoorOpen,
      tone: "blue",
    },
    {
      label: "Equipment",
      value: safeStats.totalEquipmentTypes,
      meta: "Resource types",
      icon: Boxes,
      tone: "purple",
    },
    {
      label: "Users",
      value: safeStats.totalUsers,
      meta: "System accounts",
      icon: Users,
      tone: "cyan",
    },
    {
      label: "Pending",
      value: safeStats.pendingReservations,
      meta: "Awaiting decision",
      icon: CalendarCheck,
      tone: "orange",
    },
    {
      label: "Approved",
      value: safeStats.approvedReservations,
      meta: "Confirmed bookings",
      icon: CheckCircle2,
      tone: "green",
    },
  ];

  const quickActions = [
    {
      page: "search",
      title: "Search available rooms",
      description: "Check capacity, type, equipment and time overlap.",
      icon: Search,
    },
    {
      page: "create",
      title: "Create reservation",
      description: "Submit a room or equipment request for approval.",
      icon: PlusCircle,
    },
    ...(role === "approver" || role === "admin"
        ? [
          {
            page: "approvals",
            title: "Review approvals",
            description: "Approve or reject pending reservation requests.",
            icon: ClipboardCheck,
          },
        ]
        : []),
    {
      page: "reports",
      title: "Open reports",
      description: "View advanced SQL analytical reports.",
      icon: BarChart3,
    },
    ...(role === "admin"
        ? [
          {
            page: "admin",
            title: "Admin panel",
            description: "Manage administrative project modules.",
            icon: ShieldCheck,
          },
        ]
        : []),
  ];

  return (
      <motion.div
          className="dashboard-page premium-dashboard"
          initial={{ opacity: 0, y: 18 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.45, ease: "easeOut" }}
      >
        <section className="dashboard-hero-compact">
          <div>
            <div className="dashboard-eyebrow">
              <Sparkles size={16} />
              System overview
            </div>

            <h1>Welcome back, {firstName}</h1>

            <p>
              Manage reservations, approvals, room availability and analytical
              PostgreSQL reports from one control center.
            </p>
          </div>
        </section>

        <section className="dashboard-stat-grid">
          {statCards.map((card) => {
            const Icon = card.icon;

            return (
                <motion.article
                    className={`dashboard-stat-card ${card.tone}`}
                    key={card.label}
                    whileHover={{ y: -6, scale: 1.01 }}
                    transition={{ duration: 0.18 }}
                >
                  <div className="stat-icon-wrap">
                    <Icon size={24} />
                  </div>

                  <div>
                    <span>{card.label}</span>
                    <strong>{loading ? "—" : card.value}</strong>
                    <p>{card.meta}</p>
                  </div>
                </motion.article>
            );
          })}
        </section>

        <section className="dashboard-main-grid">
          <article className="dashboard-panel quick-panel">
            <div className="panel-heading">
              <div>
                <h2>Quick actions</h2>
                <p>Frequently used reservation workflows.</p>
              </div>
            </div>

            <div className="quick-action-grid">
              {quickActions.map((action) => {
                const Icon = action.icon;

                return (
                    <button
                        key={action.page}
                        type="button"
                        onClick={() => setActivePage(action.page)}
                    >
                      <Icon size={24} />
                      <strong>{action.title}</strong>
                      <span>{action.description}</span>
                    </button>
                );
              })}
            </div>
          </article>

          <aside className="dashboard-panel status-panel">
            <div className="panel-heading">
              <div>
                <h2>System status</h2>
                <p>Current connection and access information.</p>
              </div>
            </div>

            <div className="status-stack">
              <div className="status-card database">
                <Database size={28} />
                <div>
                  <span>Status</span>
                  <strong>{databaseOnline ? "CONNECTED" : "CHECK CONNECTION"}</strong>
                  <p>Live project database · {loading ? "—" : safeStats.totalRooms} rooms loaded</p>
                </div>
              </div>

              <div className="status-card role">
                <ShieldCheck size={28} />
                <div>
                  <span>Active role</span>
                  <strong>{role.toUpperCase()}</strong>
                  <p>Your available modules depend on this role.</p>
                </div>
              </div>
            </div>
          </aside>
        </section>
      </motion.div>
  );
}

function PageMotion({ children }) {
  return (
      <motion.div
          initial={{ opacity: 0, y: 18, filter: "blur(6px)" }}
          animate={{ opacity: 1, y: 0, filter: "blur(0px)" }}
          exit={{ opacity: 0, y: -12, filter: "blur(4px)" }}
          transition={{ duration: 0.28, ease: "easeOut" }}
      >
        {children}
      </motion.div>
  );
}

function getInitials(name) {
  if (!name) {
    return "U";
  }

  return name
      .split(" ")
      .map((part) => part[0])
      .slice(0, 2)
      .join("")
      .toUpperCase();
}

export default App;