import { AppLayout, type SidebarItem } from "@/components/AppLayout";
import {
  CalendarCheck,
  Clock,
  Home,
  Layers,
  Loader2,
  MapPin,
  Receipt,
  Settings,
  Sparkles,
} from "lucide-react";
import { useDisclosure } from "@mantine/hooks";
import { useEffect, useRef } from "react";
import {
  Navigate,
  Outlet,
  Route,
  Routes,
  useLocation,
  useNavigate,
} from "react-router-dom";

import useAuth from "./hooks/useAuth";
import OnboardingWizardDialog from "./components/onboarding/OnboardingWizardDialog";
import EDRFreightLandingPage from "./pages/EDRFreightLandingPage";
import MyPortalPage from "./pages/MyPortalPage";
import MySignaturePage from "./pages/MySignaturePage";
import SettingsPage from "./pages/SettingsPage";
import LoginPage from "./pages/accounts/LoginPage";
import SetPasswordPage from "./pages/accounts/SetPasswordPage";
import SignupPage from "./pages/accounts/SignupPage";
import VerificationOtpPage from "./pages/accounts/VerificationOtpPage";
import BillingPage from "./pages/billing/BillingPage";
import BookingContractPage from "./pages/bookings/BookingContractPage";
import BookingDetailPage from "./pages/bookings/BookingDetailPage";
import EditBookingPage from "./pages/bookings/EditBookingPage";
import MyBookings from "./pages/bookings/MyBookings";
import NewBookingPage from "./pages/bookings/NewBookingPage";
import ContractsList from "./pages/contracts/ContractsList";
import ContractDetailPage from "./pages/contracts/ContractDetailPage";
import CheckPaymentPage from "./pages/payments/CheckPaymentPage";
import PaymentSuccessPage from "./pages/payments/PaymentSuccessPage";
import PaymentFailurePage from "./pages/payments/PaymentFailurePage";
import TrackingPage from "./pages/tracking/TrackingPage";

function FullScreenSpinner() {
  return (
    <div className="flex items-center justify-center h-screen">
      <Loader2 className="animate-spin text-primary" />
    </div>
  );
}

function LogoutHandler() {
  const { logout } = useAuth();
  const navigate = useNavigate();
  const hasRun = useRef(false);

  useEffect(() => {
    if (hasRun.current) return;
    hasRun.current = true;
    logout().then(() => navigate("/login", { replace: true }));
  }, []);

  return <FullScreenSpinner />;
}

/** Blocks unauthenticated users; renders children only with a valid session. */
function RequireAuth() {
  const { isPending, isAuthenticated } = useAuth();
  const location = useLocation();

  if (isPending) return <FullScreenSpinner />;
  if (!isAuthenticated)
    return <Navigate to="/login" replace state={{ from: location }} />;
  return <Outlet />;
}

/**
 * Waits for the company query so downstream routes can rely on it being
 * resolved. Onboarding is enforced by OnboardingGate, not here.
 */
function RequireCompany() {
  const { customerQuery } = useAuth();

  if (customerQuery.isPending) return <FullScreenSpinner />;
  return <Outlet />;
}

/**
 * Routes an un-onboarded user may still visit. The wizard auto-opens but is
 * dismissable, so they can browse these freely; any other route forces the
 * wizard back open and bounces them home.
 */
const ONBOARDING_ALLOWED_PATHS = ["/portal", "/signature"];

function isOnboardingAllowedPath(pathname: string): boolean {
  const path = pathname.toLowerCase();
  return ONBOARDING_ALLOWED_PATHS.some(
    (p) => path === p || path.startsWith(p + "/"),
  );
}

/**
 * Enforces first-run onboarding. The home (dashboard) and signature pages stay
 * reachable while onboarding is incomplete; the wizard auto-opens on login but
 * can be dismissed to use those pages. Visiting any other page bounces back to
 * home and re-opens the wizard. New users (no company yet) are treated the same
 * as users who haven't completed onboarding.
 */
function OnboardingGate() {
  const { company, onboardingCompleted, companyStatus } = useAuth();
  const location = useLocation();

  const needsOnboarding = !company || !onboardingCompleted;
  const allowedHere = isOnboardingAllowedPath(location.pathname);
  // Onboarding done but not yet approved by an admin → awaiting-approval state.
  const awaitingApproval = !needsOnboarding && companyStatus === "pending";

  // Open by default while onboarding is pending (covers the login case).
  const [wizardOpen, { open: openWizard, close: closeWizard }] =
    useDisclosure(false);

  // Re-evaluate on every navigation: force the wizard open on blocked routes,
  // and auto-open on first arrival while onboarding is pending.
  useEffect(() => {
    if (needsOnboarding && !allowedHere) {
      openWizard();
    }
  }, [needsOnboarding, allowedHere, location.pathname, openWizard]);

  // Auto-open once when onboarding becomes/loads as pending (login).
  const autoOpenedRef = useRef(false);
  useEffect(() => {
    if (needsOnboarding && !autoOpenedRef.current) {
      autoOpenedRef.current = true;
      openWizard();
    }
    if (!needsOnboarding) autoOpenedRef.current = false;
  }, [needsOnboarding, openWizard]);

  if (needsOnboarding && !allowedHere) {
    return <Navigate to="/portal" replace />;
  }

  return (
    <>
      {needsOnboarding && !wizardOpen && (
        <OnboardingResumeBanner onResume={openWizard} />
      )}
      {awaitingApproval && <PendingApprovalBanner />}
      <Outlet />
      <OnboardingWizardDialog
        opened={needsOnboarding && wizardOpen}
        onClose={closeWizard}
      />
    </>
  );
}

/** Slim sticky prompt shown on allowed pages after the wizard is dismissed. */
function OnboardingResumeBanner({ onResume }: { onResume: () => void }) {
  return (
    <div className="flex flex-wrap items-center justify-between gap-3 border-b border-[#0EA371]/20 bg-[#ECF6F1] px-6 py-3">
      <div className="flex items-center gap-2">
        <Sparkles size={16} className="text-[#0A6F4D]" />
        <span className="text-sm font-medium text-[#0A6F4D]">
          Finish setting up your company to unlock bookings, tracking and
          billing.
        </span>
      </div>
      <button
        type="button"
        onClick={onResume}
        className="rounded-lg bg-[#0EA371] px-4 py-2 text-sm font-semibold text-white transition-opacity hover:opacity-90"
      >
        Continue onboarding
      </button>
    </div>
  );
}

/** Shown after onboarding while the company awaits backoffice approval. */
function PendingApprovalBanner() {
  return (
    <div className="flex flex-wrap items-center gap-2 border-b border-amber-300/50 bg-amber-50 px-6 py-3">
      <Clock size={16} className="text-amber-700" />
      <span className="text-sm font-medium text-amber-800">
        Your company is awaiting EDR approval. You can browse, but creating
        bookings is disabled until your company is approved.
      </span>
    </div>
  );
}

/** Keeps authenticated users off the login/signup pages. */
function RedirectIfAuthed() {
  const { isPending, isAuthenticated } = useAuth();

  if (isPending) return <FullScreenSpinner />;
  if (isAuthenticated) return <Navigate to="/portal" replace />;
  return <Outlet />;
}

/** Landing page for visitors; authenticated users go straight to the portal. */
function LandingRoute() {
  const { isPending, isAuthenticated } = useAuth();

  if (isPending) return <FullScreenSpinner />;
  if (isAuthenticated) return <Navigate to="/portal" replace />;
  return <EDRFreightLandingPage />;
}

const sidebarItems: SidebarItem[] = [
  { label: "Home", href: "/portal", icon: <Home size={18} /> },
  {
    label: "My Bookings",
    href: "/bookings",
    icon: <CalendarCheck size={18} />,
  },
  {
    label: "General Contracts",
    href: "/contracts",
    icon: <Layers size={18} />,
  },
  {
    label: "Tracking",
    href: "/tracking",
    icon: <MapPin size={18} />,
  },
  {
    label: "Billing",
    href: "/billing",
    icon: <Receipt size={18} />,
  },
  {
    section: "Account",
    label: "Settings",
    href: "/settings",
    icon: <Settings size={18} />,
  },
];

const App = () => {
  const navigate = useNavigate();
  const location = useLocation();
  const { user, company, companyType, createProfileAndSwitch } = useAuth();

  const displayName = user?.name?.en || user?.username || user?.email || "User";
  const userEmail = user?.email;
  const companyProfiles = company?.company?.companyProfiles ?? [];

  return (
    <Routes>
      {/* Public routes */}
      <Route index element={<LandingRoute />} />
      <Route path="/logout" element={<LogoutHandler />} />
      <Route
        path="/booking/check-status/:orderId"
        element={<CheckPaymentPage />}
      />
      {/* Payment provider browser redirects (PAYMENT_RETURN_URL / PAYMENT_FAILURE_URL) */}
      <Route path="/payment/success" element={<PaymentSuccessPage />} />
      <Route path="/payment/failure" element={<PaymentFailurePage />} />

      {/* Auth pages — inaccessible once logged in */}
      <Route element={<RedirectIfAuthed />}>
        <Route path="/login" element={<LoginPage />} />
        <Route path="/signup" element={<SignupPage />} />
      </Route>

      {/* Signup-flow pages; reached while a session already exists */}
      <Route path="/otp" element={<VerificationOtpPage />} />
      <Route path="/set-password" element={<SetPasswordPage />} />

      <Route element={<RequireAuth />}>
        <Route element={<RequireCompany />}>
          <Route
            element={
              <AppLayout
                title="EDR Freight"
                sidebarItems={sidebarItems}
                activeHref={location.pathname}
                onNavigate={navigate}
                enableThemeToggle
                userName={displayName}
                userEmail={userEmail}
                companyProfiles={companyProfiles}
                companyType={companyType}
                onCreateProfile={createProfileAndSwitch}
              >
                <OnboardingGate />
              </AppLayout>
            }
          >
            <Route path="/portal" element={<MyPortalPage />} />
            <Route path="/bookings" element={<MyBookings />} />
            <Route path="/bookings/new" element={<NewBookingPage />} />
            <Route path="/bookings/:id/edit" element={<EditBookingPage />} />
            <Route path="/bookings/:id" element={<BookingDetailPage />} />
            <Route
              path="/bookings/:id/contract"
              element={<BookingContractPage />}
            />
            <Route path="/contracts" element={<ContractsList />} />
            <Route path="/contracts/:id" element={<ContractDetailPage />} />
            <Route path="/tracking" element={<TrackingPage />} />
            <Route path="/billing" element={<BillingPage />} />
            {/* Profile was merged into Settings — keep old links working. */}
            <Route path="/profile" element={<Navigate to="/settings" replace />} />
            <Route path="/signature" element={<MySignaturePage />} />
            <Route path="/settings" element={<SettingsPage />} />
          </Route>
        </Route>
      </Route>

      <Route path="*" element={<Navigate to="/" replace />} />
    </Routes>
  );
};

export default App;
