import React, { Suspense, lazy, memo, useCallback, useMemo } from "react";
import {
  BrowserRouter,
  Routes,
  Route,
  Link,
  useLocation,
  useNavigate,
  Navigate,
} from "react-router-dom";
import { useEffect, useState, useRef } from "react";
import CryptoJS from "crypto-js";

// Lazy load heavy components for better initial load time
const AdminPage = lazy(() => import("./AdminPage"));

import {
  searchExternal,
  searchLocalSongs,
  getSong,
  getSongMerged,
  saveSong,
  createSong,
  deleteSong,
  fetchPlans,
  createPlan,
  updatePlan,
  deletePlan,
  fetchPlanSongs,
  addSongToPlan,
  fetchProfiles,
  createProfile,
  updateProfile,
  deleteProfile,
  uploadLyricFile,
  exportPlanURL,
  getProfileSongs,
  addSongToProfile,
  removeSongFromProfile,
  getProfileSongKey,
  saveProfileSongKey,
  clearProfileSelection,
} from "./api";

// Mobile detection utility - detects iOS and Android mobile devices
const isMobileDevice = () => {
  if (typeof window === "undefined") return false;
  const width = window.innerWidth;
  const userAgent = navigator.userAgent || navigator.vendor || window.opera;

  // Check for true mobile devices (phones) - max 640px
  const isMobileScreen = width < 640;

  // Check for mobile user agents
  const isIOS = /iPad|iPhone|iPod/.test(userAgent) && !window.MSStream;
  const isAndroid = /android/i.test(userAgent);
  const isMobileUA = /Mobile|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
    userAgent
  );

  // Exclude tablets from mobile (iPads typically 768px+, Android tablets 600px+)
  const isTabletUA =
    /iPad|Android/i.test(userAgent) && !/Mobile/i.test(userAgent);

  return isMobileScreen && !isTabletUA && (isIOS || isAndroid || isMobileUA);
};

// Tablet detection utility - detects iPad and Android tablets
const isTabletDevice = () => {
  if (typeof window === "undefined") return false;
  const width = window.innerWidth;
  const userAgent = navigator.userAgent || navigator.vendor || window.opera;

  // Tablet screen size: between 640px and 1024px
  const isTabletScreen = width >= 640 && width < 1024;

  // Check for tablet user agents
  const isIPad = /iPad/.test(userAgent) && !window.MSStream;
  const isAndroidTablet =
    /android/i.test(userAgent) && !/Mobile/i.test(userAgent);

  return isTabletScreen || isIPad || isAndroidTablet;
};

// Hook to track mobile state with window resize
const useIsMobile = () => {
  const [isMobile, setIsMobile] = useState(false);

  useEffect(() => {
    const checkMobile = () => setIsMobile(isMobileDevice());
    checkMobile();
    window.addEventListener("resize", checkMobile);
    return () => window.removeEventListener("resize", checkMobile);
  }, []);

  return isMobile;
};

// Loading spinner component for Suspense fallback
const LoadingSpinner = () => (
  <div
    style={{
      display: "flex",
      justifyContent: "center",
      alignItems: "center",
      minHeight: "100vh",
      background: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
    }}
  >
    <div
      style={{
        textAlign: "center",
        padding: "40px",
        background: "white",
        borderRadius: "20px",
        boxShadow: "0 20px 60px rgba(0,0,0,0.3)",
      }}
    >
      <div
        className="spinner-border text-primary"
        role="status"
        style={{ width: "3rem", height: "3rem" }}
      >
        <span className="visually-hidden">Loading...</span>
      </div>
      <p style={{ marginTop: "20px", color: "#666", fontSize: "16px" }}>
        Loading...
      </p>
    </div>
  </div>
);

// Login Component
/**
 * Component to handle initial navigation after login
 */
function InitialNavigate({ to }) {
  const navigate = useNavigate();

  useEffect(() => {
    if (to && to !== "/") {
      navigate(to, { replace: true });
    }
  }, [to, navigate]);

  return null;
}

const LoginPage = memo(function LoginPage({ onLogin }) {
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");
  const [error, setError] = useState("");
  const [loading, setLoading] = useState(false);
  const [showReset, setShowReset] = useState(false);
  const [newPassword, setNewPassword] = useState("");
  const [confirmPassword, setConfirmPassword] = useState("");
  const [resetError, setResetError] = useState("");
  const [systemWarning, setSystemWarning] = useState("");
  const [biometricAvailable, setBiometricAvailable] = useState(false);
  const [biometricLoading, setBiometricLoading] = useState(false);
  const [autoPromptDone, setAutoPromptDone] = useState(false);

  // Check for system issues on mount
  useEffect(() => {
    const warnings = [];

    // Check if CryptoJS is loaded
    if (typeof CryptoJS === "undefined") {
      warnings.push(
        "Encryption library failed to load. Please refresh the page."
      );
    }

    // Check if localStorage is accessible
    try {
      localStorage.setItem("test", "test");
      localStorage.removeItem("test");
    } catch (e) {
      warnings.push(
        "Local storage is disabled. Please enable cookies/storage in your browser settings."
      );
    }

    // Check if sessionStorage is accessible
    try {
      sessionStorage.setItem("test", "test");
      sessionStorage.removeItem("test");
    } catch (e) {
      warnings.push(
        "Session storage is disabled. Please disable private/incognito mode."
      );
    }

    if (warnings.length > 0) {
      setSystemWarning(warnings.join(" "));
    }

    // Check biometric availability
    import("./biometricAuth")
      .then((module) => {
        module.isBiometricAvailable().then((result) => {
          setBiometricAvailable(result.available);
        });
      })
      .catch((err) => {
        console.log("Biometric auth not available:", err);
      });
  }, []);

  // Auto-prompt biometric if available and user has it set up
  useEffect(() => {
    if (
      biometricAvailable &&
      !autoPromptDone &&
      !loading &&
      !biometricLoading
    ) {
      const storedUsername = localStorage.getItem("masterUsername") || "hop";
      const lastBiometricUser = localStorage.getItem("lastBiometricUser");
      const shouldAutoPrompt = localStorage.getItem("biometricAutoPrompt");

      // Only auto-prompt if user previously used biometric successfully
      if (
        lastBiometricUser &&
        lastBiometricUser === storedUsername &&
        shouldAutoPrompt !== "false"
      ) {
        console.log(
          "[Login] Auto-prompting biometric authentication for",
          storedUsername
        );
        setAutoPromptDone(true);

        // Delay slightly to ensure UI is ready
        setTimeout(() => {
          handleBiometricLogin();
        }, 800);
      }
    }
  }, [biometricAvailable, autoPromptDone, loading, biometricLoading]);

  const hashPassword = useCallback((pwd) => {
    return CryptoJS.SHA256(pwd).toString();
  }, []);

  const handleLogin = useCallback(
    async (e) => {
      e.preventDefault();
      setError("");
      setLoading(true);

      try {
        // Call backend API to authenticate
        const response = await fetch("/api/auth/login", {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          credentials: "include", // Important: Send and receive cookies
          body: JSON.stringify({
            username: username.trim(),
            password: password,
          }),
        });

        const data = await response.json();

        if (response.ok && data.success) {
          // Backend created session - store authentication state locally
          const sessionId = `session_${Date.now()}_${Math.random()
            .toString(36)
            .substr(2, 9)}`;

          try {
            sessionStorage.setItem("authenticated", "true");
            sessionStorage.setItem("authTime", Date.now().toString());
            sessionStorage.setItem("sessionId", sessionId);
            sessionStorage.setItem("username", data.username);
            sessionStorage.setItem("role", data.role);
            sessionStorage.setItem(
              "permissions",
              JSON.stringify(data.permissions || [])
            );

            console.log("Login successful:", {
              username: data.username,
              role: data.role,
              permissions: data.permissions,
            });

            onLogin();
          } catch (storageErr) {
            setError(
              "Storage error: Please ensure cookies/storage is enabled and not in private browsing mode."
            );
            console.error("sessionStorage error:", storageErr);
            setLoading(false);
            return;
          }
        } else {
          // Handle error responses
          let errorMsg = "Invalid username or password";
          if (data.error === "account_disabled") {
            errorMsg =
              "Your account has been disabled. Please contact an administrator.";
          } else if (data.error === "username_password_required") {
            errorMsg = "Please enter both username and password";
          } else if (data.error === "server_error") {
            errorMsg = "Server error. Please try again later.";
          }
          setError(errorMsg);
          setPassword("");
        }
      } catch (err) {
        console.error("Login error:", err);
        setError(
          "Unable to connect to server. Please check your internet connection and try again."
        );
        setPassword("");
      } finally {
        setLoading(false);
      }
    },
    [username, password, onLogin]
  );

  const handleReset = useCallback(
    (e) => {
      e.preventDefault();
      setResetError("");

      try {
        if (!newPassword || newPassword.length < 8) {
          setResetError("Password must be at least 8 characters long");
          return;
        }

        if (newPassword !== confirmPassword) {
          setResetError("Passwords do not match");
          return;
        }

        // Hash and store new password (thread-safe - localStorage handles concurrency)
        const newHash = hashPassword(newPassword);
        localStorage.setItem("masterPasswordHash", newHash);
        localStorage.setItem("passwordLastChanged", Date.now().toString());

        setShowReset(false);
        setNewPassword("");
        setConfirmPassword("");
        setResetError("");
        setError(
          "Password reset successfully! Please login with your new password."
        );
      } catch (err) {
        setResetError("An error occurred. Please try again.");
      }
    },
    [hashPassword]
  );

  const handleBiometricLogin = useCallback(async () => {
    setBiometricLoading(true);
    setError("");

    try {
      // Import biometric auth module
      const biometricAuth = await import("./biometricAuth");

      // Authenticate using biometric - no username needed!
      console.log("[Login] Starting biometric authentication...");
      const result = await biometricAuth.authenticateBiometric();

      if (result.success) {
        // Backend returned username and user info after identifying credential
        const authenticatedUsername = result.username;
        const userRole = result.role || "viewer";
        const userPermissions = result.permissions || [];

        console.log(
          "[Login] Biometric auth successful for:",
          authenticatedUsername
        );

        // Set session with user info from backend
        try {
          const sessionId = `session_${Date.now()}_${Math.random()
            .toString(36)
            .substr(2, 9)}`;

          sessionStorage.setItem("authenticated", "true");
          sessionStorage.setItem("authTime", Date.now().toString());
          sessionStorage.setItem("sessionId", sessionId);
          sessionStorage.setItem("biometricAuth", "true");
          sessionStorage.setItem("username", authenticatedUsername);
          sessionStorage.setItem("role", userRole);
          sessionStorage.setItem(
            "permissions",
            JSON.stringify(userPermissions)
          );

          // Remember this user for future reference
          localStorage.setItem("lastBiometricUser", authenticatedUsername);
          localStorage.setItem("biometricAutoPrompt", "true");

          console.log("[Login] Session created, logging in...");
          onLogin();
        } catch (storageErr) {
          setError("Storage error: Please ensure cookies/storage is enabled.");
          return;
        }
      } else {
        setError(`Biometric authentication failed: ${result.error}`);
      }
    } catch (err) {
      console.error("Biometric login error:", err);
      setError(`Biometric login failed: ${err.message}`);
    } finally {
      setBiometricLoading(false);
    }
  }, [onLogin]);

  return (
    <div
      className="min-vh-100 d-flex align-items-center justify-content-center"
      style={{
        background:
          "linear-gradient(135deg, #00d4ff 0%, #00a8ff 25%, #6e5ff0 50%, #a855f7 75%, #ec4899 100%)",
        minHeight: "100vh",
        width: "100%",
      }}
      role="main"
      aria-label="Login page"
    >
      <a href="#login-form" className="skip-link">
        Skip to login form
      </a>
      <div
        className="container"
        style={{ maxWidth: "100%", padding: "0 1rem" }}
      >
        <div className="row justify-content-center">
          <div
            className="col-12 col-md-6 col-lg-4"
            style={{ maxWidth: "100%" }}
          >
            <div
              className="card shadow-lg border-0 rounded-3"
              style={{ width: "100%", maxWidth: "440px", margin: "0 auto" }}
            >
              <div className="card-body" style={{ padding: "1.5rem" }}>
                {/* Logo/Title */}
                <div className="text-center mb-3">
                  <div className="mb-2">
                    <img
                      src="/church-logo.png"
                      alt="House of Prayer Worship Logo"
                      style={{
                        height: "clamp(120px, 30vw, 180px)",
                        width: "auto",
                        maxWidth: "100%",
                        objectFit: "contain",
                        display: "block",
                        margin: "0 auto",
                      }}
                    />
                  </div>
                  <h1
                    style={{
                      fontSize: "clamp(1.25rem, 5vw, 1.75rem)",
                      fontWeight: "700",
                    }}
                    className="text-dark mb-2"
                  >
                    HOP Worship App
                  </h1>
                  <p
                    style={{ fontSize: "0.875rem" }}
                    className="text-muted mb-0"
                  >
                    Worship Song Database
                  </p>
                </div>

                {!showReset ? (
                  /* Login Form */
                  <form
                    onSubmit={handleLogin}
                    id="login-form"
                    aria-label="Login form"
                  >
                    {systemWarning && (
                      <div
                        className="alert alert-warning alert-dismissible fade show"
                        role="alert"
                        aria-live="polite"
                      >
                        <i
                          className="bi bi-exclamation-triangle-fill me-2"
                          aria-hidden="true"
                        ></i>
                        <strong>System Warning:</strong>
                        <br />
                        {systemWarning}
                        <button
                          type="button"
                          className="btn-close"
                          onClick={() => setSystemWarning("")}
                          aria-label="Close system warning"
                        ></button>
                      </div>
                    )}

                    {error && (
                      <div
                        className="alert alert-danger alert-dismissible fade show"
                        role="alert"
                        aria-live="assertive"
                      >
                        <i
                          className="bi bi-exclamation-circle me-2"
                          aria-hidden="true"
                        ></i>
                        {error}
                        <button
                          type="button"
                          className="btn-close"
                          onClick={() => setError("")}
                          aria-label="Close error message"
                        ></button>
                      </div>
                    )}

                    <div className="mb-3">
                      <label
                        htmlFor="username"
                        className="form-label"
                        style={{ fontSize: "0.875rem", fontWeight: "600" }}
                      >
                        <i
                          className="bi bi-person-fill me-2"
                          aria-hidden="true"
                        ></i>
                        Username
                      </label>
                      <input
                        type="text"
                        id="username"
                        name="username"
                        className="form-control"
                        style={{ fontSize: "1rem", padding: "0.5rem 0.75rem" }}
                        value={username}
                        onChange={(e) => setUsername(e.target.value)}
                        onKeyDown={(e) => {
                          if (e.key === "Enter" && !loading) {
                            e.preventDefault();
                            handleLogin(e);
                          }
                        }}
                        placeholder="Enter username"
                        autoFocus
                        autoComplete="username"
                        disabled={loading}
                        required
                        aria-required="true"
                        aria-label="Username"
                        aria-describedby={error ? "login-error" : undefined}
                      />
                    </div>

                    <div className="mb-3">
                      <label
                        htmlFor="password"
                        className="form-label"
                        style={{ fontSize: "0.875rem", fontWeight: "600" }}
                      >
                        <i
                          className="bi bi-lock-fill me-2"
                          aria-hidden="true"
                        ></i>
                        Password
                      </label>
                      <input
                        type="password"
                        id="password"
                        name="password"
                        className="form-control"
                        style={{ fontSize: "1rem", padding: "0.5rem 0.75rem" }}
                        value={password}
                        onChange={(e) => setPassword(e.target.value)}
                        onKeyDown={(e) => {
                          if (e.key === "Enter" && !loading) {
                            e.preventDefault();
                            handleLogin(e);
                          }
                        }}
                        placeholder="Enter password"
                        autoComplete="current-password"
                        disabled={loading}
                        required
                        aria-required="true"
                        aria-label="Password"
                        aria-describedby={error ? "login-error" : undefined}
                      />
                    </div>

                    {/* Three buttons - responsive layout */}
                    <div
                      className="d-flex mb-3"
                      style={{
                        gap: "0.5rem",
                        flexWrap: "wrap",
                        justifyContent: "center",
                      }}
                      role="group"
                      aria-label="Login actions"
                    >
                      <button
                        type="submit"
                        className="btn text-white"
                        disabled={loading}
                        aria-busy={loading}
                        aria-label={
                          loading ? "Logging in, please wait" : "Login"
                        }
                        style={{
                          background:
                            "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
                          borderRadius: "8px",
                          padding: "0.625rem 1rem",
                          fontSize: "0.875rem",
                          fontWeight: "600",
                          flex: "1 1 auto",
                          minWidth: "90px",
                          border: "none",
                          display: "flex",
                          alignItems: "center",
                          justifyContent: "center",
                          gap: "0.375rem",
                          lineHeight: "1.3",
                        }}
                      >
                        {loading ? (
                          <>
                            <span
                              className="spinner-border spinner-border-sm"
                              role="status"
                              aria-hidden="true"
                              style={{
                                width: "0.875rem",
                                height: "0.875rem",
                                flexShrink: 0,
                              }}
                            ></span>
                            <span
                              style={{ flexShrink: 0, whiteSpace: "nowrap" }}
                            >
                              Signing in...
                            </span>
                          </>
                        ) : (
                          <>
                            <i
                              className="bi bi-box-arrow-in-right"
                              aria-hidden="true"
                              style={{
                                fontSize: "1.125rem",
                                flexShrink: 0,
                                display: "inline-flex",
                                alignItems: "center",
                              }}
                            ></i>
                            <span
                              style={{ flexShrink: 0, whiteSpace: "nowrap" }}
                            >
                              Login
                            </span>
                          </>
                        )}
                      </button>

                      {biometricAvailable && (
                        <button
                          type="button"
                          onClick={handleBiometricLogin}
                          aria-label={
                            biometricLoading
                              ? "Authenticating with biometrics"
                              : "Login with biometrics"
                          }
                          aria-busy={biometricLoading}
                          disabled={biometricLoading}
                          className="btn"
                          style={{
                            background:
                              "linear-gradient(135deg, #10b981 0%, #059669 100%)",
                            color: "white",
                            border: "none",
                            borderRadius: "8px",
                            padding: "0.625rem 1rem",
                            fontSize: "0.875rem",
                            fontWeight: "600",
                            flex: "1 1 auto",
                            minWidth: "110px",
                            display: "flex",
                            alignItems: "center",
                            justifyContent: "center",
                            gap: "0.375rem",
                            lineHeight: "1.3",
                          }}
                        >
                          {biometricLoading ? (
                            <>
                              <span
                                className="spinner-border spinner-border-sm"
                                role="status"
                                aria-hidden="true"
                                style={{
                                  width: "0.875rem",
                                  height: "0.875rem",
                                  flexShrink: 0,
                                }}
                              ></span>
                              <span
                                style={{ flexShrink: 0, whiteSpace: "nowrap" }}
                              >
                                Auth...
                              </span>
                            </>
                          ) : (
                            <>
                              <i
                                className="bi bi-fingerprint"
                                style={{
                                  fontSize: "1.125rem",
                                  flexShrink: 0,
                                  display: "inline-flex",
                                  alignItems: "center",
                                }}
                              ></i>
                              <span
                                style={{ flexShrink: 0, whiteSpace: "nowrap" }}
                              >
                                Biometric
                              </span>
                            </>
                          )}
                        </button>
                      )}

                      <button
                        type="button"
                        className="btn"
                        onClick={() => setShowReset(true)}
                        style={{
                          background:
                            "linear-gradient(135deg, #f59e0b 0%, #d97706 100%)",
                          color: "white",
                          border: "none",
                          borderRadius: "8px",
                          padding: "0.625rem 1rem",
                          fontSize: "0.875rem",
                          fontWeight: "600",
                          flex: "1 1 auto",
                          minWidth: "90px",
                          display: "flex",
                          alignItems: "center",
                          justifyContent: "center",
                          gap: "0.375rem",
                          lineHeight: "1.3",
                        }}
                      >
                        <i
                          className="bi bi-key-fill"
                          style={{
                            fontSize: "1.125rem",
                            flexShrink: 0,
                            display: "inline-flex",
                            alignItems: "center",
                          }}
                        ></i>
                        <span style={{ flexShrink: 0, whiteSpace: "nowrap" }}>
                          Reset
                        </span>
                      </button>
                    </div>
                  </form>
                ) : (
                  /* Password Reset Form */
                  <form onSubmit={handleReset}>
                    <div className="mb-3">
                      <button
                        type="button"
                        className="btn btn-sm btn-link text-decoration-none p-0 mb-3"
                        onClick={() => {
                          setShowReset(false);
                          setResetError("");
                          setNewPassword("");
                          setConfirmPassword("");
                        }}
                      >
                        <i className="bi bi-arrow-left me-2"></i>
                        Back to Login
                      </button>
                    </div>

                    <h4 className="fw-bold mb-3">Reset Password</h4>

                    {resetError && (
                      <div
                        className="alert alert-danger alert-dismissible fade show"
                        role="alert"
                      >
                        <i className="bi bi-exclamation-circle me-2"></i>
                        {resetError}
                        <button
                          type="button"
                          className="btn-close"
                          onClick={() => setResetError("")}
                        ></button>
                      </div>
                    )}

                    <div className="mb-3">
                      <label
                        htmlFor="newPassword"
                        className="form-label fw-semibold"
                      >
                        New Password
                      </label>
                      <input
                        type="password"
                        id="newPassword"
                        className="form-control"
                        value={newPassword}
                        onChange={(e) => setNewPassword(e.target.value)}
                        placeholder="Enter new password (min 8 characters)"
                        required
                      />
                    </div>

                    <div className="mb-3">
                      <label
                        htmlFor="confirmPassword"
                        className="form-label fw-semibold"
                      >
                        Confirm Password
                      </label>
                      <input
                        type="password"
                        id="confirmPassword"
                        className="form-control"
                        value={confirmPassword}
                        onChange={(e) => setConfirmPassword(e.target.value)}
                        placeholder="Confirm new password"
                        required
                      />
                    </div>

                    <button
                      type="submit"
                      className="btn btn-success btn-lg w-100"
                    >
                      <i className="bi bi-check-circle me-2"></i>
                      Reset Password
                    </button>
                  </form>
                )}

                {/* Footer */}
                <div className="text-center mt-4 pt-3 border-top">
                  <p
                    className="mb-0"
                    style={{
                      fontSize: "0.75rem",
                      color: "#6b7280",
                      fontWeight: "500",
                      letterSpacing: "0.5px",
                    }}
                  >
                    <i
                      className="bi bi-shield-lock-fill me-2"
                      style={{ fontSize: "0.875rem" }}
                    ></i>
                    Secure Access • Encrypted Storage
                  </p>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
});

function Home() {
  const navigate = useNavigate();
  const isMobile = useIsMobile();

  const [q, setQ] = useState("");
  const [filterType, setFilterType] = useState("all");
  // Removed source toggle; external search is combined
  const [results, setResults] = useState([]);
  const [modal, setModal] = useState(null);
  const [profiles, setProfiles] = useState([]);
  const [selectedProfile, setSelectedProfile] = useState(null);
  const [plans, setPlans] = useState([]);
  const [latestPlan, setLatestPlan] = useState(null);
  const [showCreateDay, setShowCreateDay] = useState(false);
  const [editingPlan, setEditingPlan] = useState(null);
  const [newDate, setNewDate] = useState("");
  const [planNotes, setPlanNotes] = useState("");
  const [planSongSearch, setPlanSongSearch] = useState("");
  const [planSearchResults, setPlanSearchResults] = useState([]);
  const [chosenSongs, setChosenSongs] = useState([]);
  const [draggedSongIndex, setDraggedSongIndex] = useState(null);
  const [touchStartY, setTouchStartY] = useState(null);
  const [addedSongId, setAddedSongId] = useState(null);
  const [viewingPlan, setViewingPlan] = useState(null);
  const [viewingPlanSong, setViewingPlanSong] = useState(null);
  const [hoveredPlan, setHoveredPlan] = useState(null);
  const [deleteConfirmPlan, setDeleteConfirmPlan] = useState(null);
  const [searching, setSearching] = useState(false);
  const [error, setError] = useState(null);
  const [uploadFile, setUploadFile] = useState(null);
  const [uploading, setUploading] = useState(false);
  const [uploadError, setUploadError] = useState(null);
  const [showBlankSheet, setShowBlankSheet] = useState(false);
  const [showSingerSelector, setShowSingerSelector] = useState(false);

  // Touch gesture state for swipe-to-go-back
  const [touchStart, setTouchStart] = useState(null);
  const [touchEnd, setTouchEnd] = useState(null);
  const minSwipeDistance = 50;

  // Lock body scroll when any modal is open - simplified to avoid layout shifts
  // Only lock on desktop or when modals are shown
  useEffect(() => {
    const shouldLock =
      !isMobile &&
      (modal ||
        viewingPlan ||
        viewingPlanSong ||
        showCreateDay ||
        editingPlan ||
        deleteConfirmPlan ||
        showBlankSheet ||
        showSingerSelector);
    if (shouldLock) {
      const originalOverflow = document.body.style.overflow;
      const scrollY = window.scrollY;

      document.body.style.overflow = "hidden";
      document.body.style.touchAction = "none";

      return () => {
        document.body.style.overflow = originalOverflow;
        document.body.style.touchAction = "";
        window.scrollTo(0, scrollY);
      };
    }
  }, [
    modal,
    viewingPlan,
    viewingPlanSong,
    showCreateDay,
    editingPlan,
    deleteConfirmPlan,
    showBlankSheet,
    showSingerSelector,
  ]);

  // Handle browser back button
  useEffect(() => {
    const handlePopState = (event) => {
      event.preventDefault();

      // Close modals in reverse order (most recent first)
      if (showSingerSelector) {
        setShowSingerSelector(false);
      } else if (showBlankSheet) {
        setShowBlankSheet(false);
      } else if (viewingPlanSong) {
        setViewingPlanSong(null);
      } else if (viewingPlan) {
        setViewingPlan(null);
      } else if (deleteConfirmPlan) {
        setDeleteConfirmPlan(null);
      } else if (editingPlan || showCreateDay) {
        setEditingPlan(null);
        setShowCreateDay(false);
      } else if (modal) {
        setModal(null);
      } else {
        // No modals open, allow normal navigation
        return;
      }

      // Re-push state to prevent actual navigation away from page
      window.history.pushState(
        {
          page: "home",
          preventNav: true,
        },
        "",
        window.location.pathname + window.location.search
      );
    };

    window.addEventListener("popstate", handlePopState);
    return () => window.removeEventListener("popstate", handlePopState);
  }, [
    modal,
    showCreateDay,
    editingPlan,
    viewingPlan,
    viewingPlanSong,
    deleteConfirmPlan,
    showBlankSheet,
    showSingerSelector,
  ]);

  // Handle swipe gestures
  const onTouchStart = (e) => {
    setTouchEnd(null);
    setTouchStart(e.targetTouches[0].clientX);
  };

  const onTouchMove = (e) => {
    setTouchEnd(e.targetTouches[0].clientX);
  };

  const onTouchEnd = () => {
    if (!touchStart || !touchEnd) return;
    const distance = touchStart - touchEnd;
    const isRightSwipe = distance < -minSwipeDistance;

    if (isRightSwipe && touchStart < 50) {
      if (showSingerSelector) {
        setShowSingerSelector(false);
      } else if (showBlankSheet) {
        setShowBlankSheet(false);
      } else if (viewingPlanSong) {
        setViewingPlanSong(null);
      } else if (viewingPlan) {
        setViewingPlan(null);
      } else if (deleteConfirmPlan) {
        setDeleteConfirmPlan(null);
      } else if (editingPlan || showCreateDay) {
        setEditingPlan(null);
        setShowCreateDay(false);
      } else if (modal) {
        setModal(null);
      }
    }
  };

  // Initialize history state on mount
  useEffect(() => {
    // Push initial state to create a history entry for this page
    window.history.replaceState(
      {
        page: "home",
        isInitial: true,
      },
      "",
      window.location.pathname + window.location.search
    );
  }, []);

  // Load profiles and plans on mount
  useEffect(() => {
    loadProfiles();
    loadPlans();
  }, []);

  useEffect(() => {
    // Listen for plan changes from Planning component
    const handlePlansChange = () => {
      loadPlans(); // Reload plans when they change
    };
    const handleSongsChange = () => {
      // Reload results if currently showing search results
      if (results.length > 0 && q.trim()) {
        doSearch();
      }
    };
    window.addEventListener("plansChanged", handlePlansChange);
    window.addEventListener("songsChanged", handleSongsChange);

    return () => {
      window.removeEventListener("plansChanged", handlePlansChange);
      window.removeEventListener("songsChanged", handleSongsChange);
    };
  }, []);

  // Helper functions to open modals with history support
  const openModal = (song) => {
    setModal(song);
    window.history.pushState(
      {
        modal: "song",
        songId: song.id,
        returnTo: "home",
      },
      "",
      window.location.pathname + window.location.search
    );
  };

  const closeModal = () => {
    setModal(null);
  };

  const openViewingPlan = (plan) => {
    setViewingPlan(plan);
    window.history.pushState(
      {
        modal: "viewingPlan",
        planId: plan.id,
        returnTo: "home",
      },
      "",
      window.location.pathname + window.location.search
    );
  };

  const closeViewingPlan = () => {
    setViewingPlan(null);
  };

  const openViewingPlanSong = (song) => {
    setViewingPlanSong(song);
    window.history.pushState(
      {
        modal: "viewingPlanSong",
        songId: song.id,
        returnTo: "viewingPlan",
      },
      "",
      window.location.pathname + window.location.search
    );
  };

  const closeViewingPlanSong = () => {
    setViewingPlanSong(null);
  };

  async function loadProfiles() {
    const p = await fetchProfiles();
    setProfiles(p || []);
    // Load saved profile from localStorage
    const savedId = localStorage.getItem("selected_profile_id");
    if (savedId && p) {
      const saved = p.find((prof) => prof.id.toString() === savedId);
      setSelectedProfile(saved ? saved.id : p.length > 0 ? p[0].id : null);
    } else if (p && p.length > 0) {
      setSelectedProfile(p[0].id);
    }
  }

  async function loadPlans() {
    const p = await fetchPlans();
    if (p && p.length > 0) {
      // Load full song data for each plan
      const plansWithSongs = await Promise.all(
        p.map(async (plan) => {
          const songs = await fetchPlanSongs(plan.id);
          const fullSongs = await Promise.all(
            (songs || []).map(async (ps) => {
              const song = await getSongMerged(ps.song_id);
              return { ...song, order: ps.order_index };
            })
          );
          return { ...plan, songs: fullSongs };
        })
      );
      setPlans(plansWithSongs);

      // Set latest plan
      if (plansWithSongs.length > 0) {
        const sorted = [...plansWithSongs].sort((a, b) =>
          a.date > b.date ? -1 : 1
        );
        setLatestPlan(sorted[0]);
      } else {
        setLatestPlan(null);
      }
    } else {
      setPlans([]);
      setLatestPlan(null);
    }
  }

  async function doSearch() {
    if (!q.trim()) {
      setError("Please enter a search term");
      return;
    }

    setSearching(true);
    setError(null);
    setResults([]);

    try {
      const data = await searchExternal(q, filterType);
      setResults(data.results || []);
      if (!data.results || data.results.length === 0) {
        setError("No results found. Try a different search term.");
      }
    } catch (err) {
      setError("Search failed. Please try again.");
    } finally {
      setSearching(false);
    }
  }

  async function openPreview(item) {
    setModal({
      id: null,
      title: item.title,
      artist: item.artist,
      band: item.band,
      lyrics: item.snippet || "",
      chords: "",
      source: item.source,
    });
  }

  async function saveToDatabase() {
    if (!modal) return;

    // Validate required fields
    if (!modal.title || modal.title.trim() === "") {
      alert("Song title is required");
      return;
    }

    if (!modal.lyrics || modal.lyrics.trim() === "") {
      alert("Song lyrics are required");
      return;
    }

    try {
      if (modal.id) {
        await saveSong(modal.id, {
          title: modal.title.trim(),
          artist: modal.artist?.trim() || "",
          band: modal.band?.trim() || "",
          lyrics: modal.lyrics.trim(),
          chords: modal.chords?.trim() || "",
          singer: modal.singer?.trim() || "",
        });
        const full = await getSong(modal.id);
        setModal(full);
        // Trigger sync event for other components/devices
        window.dispatchEvent(
          new CustomEvent("songsChanged", { detail: { id: modal.id } })
        );
      } else {
        const created = await createSong({
          title: modal.title.trim(),
          artist: modal.artist?.trim() || "",
          band: modal.band?.trim() || "",
          lyrics: modal.lyrics.trim(),
          chords: modal.chords?.trim() || "",
          singer: modal.singer?.trim() || "",
        });

        if (!created || !created.id) {
          throw new Error("Failed to create song");
        }

        const full = await getSong(created.id);
        setModal(full);
        // Trigger sync event for other components/devices
        window.dispatchEvent(
          new CustomEvent("songsChanged", { detail: { id: created.id } })
        );
      }
    } catch (error) {
      console.error("Error saving song:", error);
      alert("Failed to save song. Please try again.");
    }
  }

  async function createNewDay() {
    if (!newDate) return;

    if (!selectedProfile) {
      alert("Please select a profile before creating a worship list");
      return;
    }

    const planData = {
      date: newDate,
      profile_id: selectedProfile,
      notes: planNotes,
    };

    try {
      let planId;
      if (editingPlan) {
        // When editing, pass songs to updatePlan so it clears old ones
        await updatePlan(editingPlan.id, {
          ...planData,
          songs: chosenSongs,
        });
        planId = editingPlan.id;
      } else {
        const created = await createPlan(planData);
        if (!created || !created.id) {
          throw new Error("Failed to create plan");
        }
        planId = created.id;

        // Add songs to the new plan in parallel for speed
        if (chosenSongs.length > 0) {
          console.log(
            `[Worship List] Adding ${chosenSongs.length} songs to plan ${planId}`
          );
          console.log("[Worship List] Chosen songs:", chosenSongs);

          const addResults = await Promise.all(
            chosenSongs.map(async (song, i) => {
              console.log(
                `[Worship List] Adding song ${i}: ID=${song.id}, Title=${song.title}`
              );
              const result = await addSongToPlan(planId, {
                song_id: song.id,
                order_index: i,
              });
              console.log(`[Worship List] Song ${i} add result:`, result);
              return result;
            })
          );
          console.log("[Worship List] All songs added, results:", addResults);
        } else {
          console.log("[Worship List] No songs to add");
        }
      }

      // Close modal immediately for better UX
      closePlanModal();

      // Reload in background
      await loadPlans();
      // Notify Planning component to reload plans
      window.dispatchEvent(new Event("plansChanged"));
    } catch (error) {
      console.error("Error creating/editing worship list:", error);
      alert(
        `Failed to ${
          editingPlan ? "update" : "create"
        } worship list. Please try again.`
      );
    }
  }

  function closePlanModal() {
    setShowCreateDay(false);
    setEditingPlan(null);
    setNewDate("");
    setPlanNotes("");
    setChosenSongs([]);
    setPlanSongSearch("");
    setPlanSearchResults([]);
  }

  function openEditPlan(plan) {
    setEditingPlan(plan);
    setNewDate(plan.date);
    setPlanNotes(plan.notes || "");
    setChosenSongs(plan.songs || []);
    setShowCreateDay(true);
    setViewingPlan(null);
  }

  async function handleDeletePlan(planId) {
    if (!deleteConfirmPlan) return;

    try {
      console.log("=== START DELETE PROCESS ===");
      console.log("handleDeletePlan - Deleting plan:", planId);

      // Delete the plan
      const result = await deletePlan(planId);
      console.log("Delete result:", result);

      // Close modals immediately
      setDeleteConfirmPlan(null);
      setViewingPlan(null);

      // Clear the current plans state to force fresh fetch
      setPlans([]);
      setLatestPlan(null);

      // Small delay to ensure backend has committed the change
      await new Promise((resolve) => setTimeout(resolve, 100));

      // Force complete refresh of plans
      console.log("Reloading plans...");
      await loadPlans();

      // Notify Planning component to reload
      window.dispatchEvent(new Event("plansChanged"));

      console.log("=== DELETE PROCESS COMPLETE ===");
    } catch (error) {
      console.error("Error deleting plan:", error);
      alert("Failed to delete worship list. Please try again.");
    }
  }

  async function searchPlanSongs() {
    if (!planSongSearch.trim()) {
      setPlanSearchResults([]);
      return;
    }
    const results = await searchLocalSongs(planSongSearch);
    const validResults = (results || []).filter(
      (song) =>
        song.title &&
        song.title.trim() !== "" &&
        song.title.trim().toLowerCase() !== "untitled"
    );
    setPlanSearchResults(validResults);
  }

  function addSongToChosen(song) {
    if (!chosenSongs.find((s) => s.id === song.id)) {
      setChosenSongs([...chosenSongs, song]);

      // Check if search matches artist/band/singer (keep search) or song title (clear search)
      const searchLower = planSongSearch.toLowerCase().trim();
      const artistMatch = (song.artist || "")
        .toLowerCase()
        .includes(searchLower);
      const bandMatch = (song.band || "").toLowerCase().includes(searchLower);
      const singerMatch = (song.singer || "")
        .toLowerCase()
        .includes(searchLower);
      const titleMatch = (song.title || "").toLowerCase().includes(searchLower);

      // If searching by artist/band/singer, keep the search
      // If searching by title only, clear it
      const isArtistSearch =
        (artistMatch || bandMatch || singerMatch) && !titleMatch;

      if (!isArtistSearch) {
        // Clear search only if it was a title search
        setPlanSongSearch("");
      }
    }
  }

  function removeSongFromChosen(songId) {
    setChosenSongs(chosenSongs.filter((s) => s.id !== songId));
  }

  function moveSongUp(index) {
    if (index === 0) return;
    const newSongs = [...chosenSongs];
    [newSongs[index - 1], newSongs[index]] = [
      newSongs[index],
      newSongs[index - 1],
    ];
    setChosenSongs(newSongs);
  }

  function moveSongDown(index) {
    if (index === chosenSongs.length - 1) return;
    const newSongs = [...chosenSongs];
    [newSongs[index], newSongs[index + 1]] = [
      newSongs[index + 1],
      newSongs[index],
    ];
    setChosenSongs(newSongs);
  }

  // Drag and drop handlers (for desktop)
  function handleDragStart(e, index) {
    setDraggedSongIndex(index);
    e.dataTransfer.effectAllowed = "move";
    e.dataTransfer.setData("text/html", e.currentTarget);
    e.currentTarget.classList.add("dragging");
  }

  function handleDragEnd(e) {
    e.currentTarget.classList.remove("dragging");
    setDraggedSongIndex(null);
  }

  function handleDragOver(e) {
    e.preventDefault();
    e.dataTransfer.dropEffect = "move";
    return false;
  }

  function handleDrop(e, dropIndex) {
    e.preventDefault();
    e.stopPropagation();

    if (draggedSongIndex === null || draggedSongIndex === dropIndex) return;

    const newSongs = [...chosenSongs];
    const draggedSong = newSongs[draggedSongIndex];
    newSongs.splice(draggedSongIndex, 1);
    newSongs.splice(dropIndex, 0, draggedSong);

    setChosenSongs(newSongs);
    setDraggedSongIndex(null);
  }

  // Touch handlers (for mobile)
  function handleTouchStart(e, index) {
    setDraggedSongIndex(index);
    setTouchStartY(e.touches[0].clientY);
  }

  function handleTouchMove(e) {
    if (draggedSongIndex === null) return;
    e.preventDefault();
  }

  function handleTouchEnd(e, dropIndex) {
    if (draggedSongIndex === null) return;

    if (draggedSongIndex !== dropIndex) {
      const newSongs = [...chosenSongs];
      const draggedSong = newSongs[draggedSongIndex];
      newSongs.splice(draggedSongIndex, 1);
      newSongs.splice(dropIndex, 0, draggedSong);
      setChosenSongs(newSongs);
    }

    setDraggedSongIndex(null);
    setTouchStartY(null);
  }

  // Navigate to next song in worship plan
  async function navigateToNextSong() {
    if (!viewingPlan || !viewingPlan.songs || !viewingPlanSong) return;

    const currentIndex = viewingPlan.songs.findIndex(
      (s) => s.id === viewingPlanSong.id
    );
    if (currentIndex < viewingPlan.songs.length - 1) {
      const nextSong = viewingPlan.songs[currentIndex + 1];
      const fullSong = await getSongMerged(nextSong.id);
      setViewingPlanSong(fullSong);
    }
  }

  // Navigate to previous song in worship plan
  async function navigateToPrevSong() {
    if (!viewingPlan || !viewingPlan.songs || !viewingPlanSong) return;

    const currentIndex = viewingPlan.songs.findIndex(
      (s) => s.id === viewingPlanSong.id
    );
    if (currentIndex > 0) {
      const prevSong = viewingPlan.songs[currentIndex - 1];
      const fullSong = await getSongMerged(prevSong.id);
      setViewingPlanSong(fullSong);
    }
  }

  useEffect(() => {
    searchPlanSongs();
  }, [planSongSearch]);

  // Debounce automatic search when user types in main search box
  useEffect(() => {
    if (!q.trim()) {
      setResults([]);
      setError(null);
      return;
    }
    const handle = setTimeout(() => {
      // Trigger search automatically after short pause
      doSearch();
    }, 350); // 350ms debounce
    return () => clearTimeout(handle);
  }, [q, filterType]);

  async function handleUpload() {
    if (!uploadFile) return;
    setUploading(true);
    setUploadError(null);
    try {
      const res = await uploadLyricFile(uploadFile, { port: "5001" });
      if (res.error) {
        setUploadError(
          res.error === "extraction_failed"
            ? "Could not extract text from file."
            : "Upload failed."
        );
      } else {
        setModal({
          id: null,
          title: res.title || "Uploaded Song",
          artist: res.artist || "",
          band: res.band || "",
          lyrics: res.lyrics || "",
          chords: "",
        });
        setUploadFile(null);
      }
    } catch (e) {
      setUploadError("Upload failed. Ensure backend running.");
    } finally {
      setUploading(false);
    }
  }

  function createBlankSheet() {
    setModal({
      id: null,
      title: "",
      artist: "",
      band: "",
      lyrics: "",
      chords: "",
      isBlankSheet: true,
    });
    setShowBlankSheet(false);
  }

  return (
    <main
      className="px-2 py-4 sm:px-6 sm:py-6 md:px-6 md:py-6 max-w-7xl mx-auto"
      style={{ WebkitTextSizeAdjust: "100%" }}
    >
      {/* Worship Lists Section - Moved to Top */}
      <div className="bg-white p-3 sm:p-4 md:p-5 rounded-xl shadow-md mb-6 border border-gray-200">
        <div className="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 mb-5">
          <h3
            className="text-xl font-bold text-gray-800 flex items-center gap-2"
            style={{ fontSize: "clamp(1.125rem, 4vw, 1.25rem)" }}
          >
            <span>📋</span> Worship Lists
          </h3>
          <button
            onClick={() => {
              setEditingPlan(null);
              setNewDate("");
              setPlanNotes("");
              setChosenSongs([]);
              setShowCreateDay(true);
            }}
            type="button"
            aria-label="Create new worship list"
            className="w-full sm:w-auto px-5 py-2.5 sm:px-6 sm:py-3 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition-colors font-semibold shadow-md"
            style={{
              border: "none",
              cursor: "pointer",
              fontSize: "clamp(0.875rem, 3.5vw, 1rem)",
            }}
          >
            ➕ Create Worship List
          </button>
        </div>

        {latestPlan && (
          <div
            onClick={() => {
              if (isMobile) {
                // On mobile: navigate to full-page view with plan data in state
                navigate("/view-worship-plan", {
                  state: { plan: latestPlan, plans, fromLatest: true },
                });
              } else {
                // On desktop: open modal
                setViewingPlan(latestPlan);
              }
            }}
            style={{
              background: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
              borderRadius: 16,
              padding: "24px",
              marginBottom: 20,
              cursor: "pointer",
              boxShadow: "0 4px 16px rgba(0,0,0,0.15)",
              transition: "all 0.3s ease",
              minHeight: 160,
              display: "flex",
              flexDirection: "column",
              justifyContent: "center",
              alignItems: "center",
            }}
            onMouseEnter={(e) => {
              e.currentTarget.style.transform = "translateY(-4px)";
              e.currentTarget.style.boxShadow = "0 8px 24px rgba(0,0,0,0.25)";
            }}
            onMouseLeave={(e) => {
              e.currentTarget.style.transform = "translateY(0)";
              e.currentTarget.style.boxShadow = "0 4px 16px rgba(0,0,0,0.15)";
            }}
          >
            <div
              style={{
                fontSize: "clamp(0.75rem, 3vw, 0.875rem)",
                color: "rgba(255,255,255,0.9)",
                marginBottom: 8,
              }}
            >
              📋 Most Recent Worship List
            </div>
            <div
              style={{
                fontWeight: "bold",
                fontSize: "clamp(1.25rem, 4.5vw, 2rem)",
                color: "white",
                marginBottom: 12,
                textAlign: "center",
                padding: "0 12px",
              }}
            >
              {(() => {
                const [year, month, day] = latestPlan.date.split("-");
                return new Date(year, month - 1, day).toLocaleDateString(
                  "en-US",
                  {
                    weekday: "long",
                    month: "long",
                    day: "numeric",
                    year: "numeric",
                  }
                );
              })()}
            </div>
            <div
              style={{
                fontSize: "clamp(0.75rem, 3vw, 0.8125rem)",
                color: "rgba(255,255,255,0.85)",
                padding: "8px 16px",
                background: "rgba(255,255,255,0.15)",
                borderRadius: 20,
                maxWidth: "90%",
                textAlign: "center",
              }}
            >
              {latestPlan.notes || "Click to view and edit this worship list"}
            </div>
          </div>
        )}

        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-4">
          {(plans || []).map((p) => (
            <div
              key={p.id}
              onClick={() => {
                if (isMobile) {
                  // On mobile: navigate to full-page view
                  navigate("/view-worship-plan", { state: { plan: p, plans } });
                } else {
                  // On desktop: open modal
                  setViewingPlan(p);
                }
              }}
              className="worship-card"
              style={{
                background: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
                borderRadius: 12,
                padding: "16px 20px",
                cursor: "pointer",
                minHeight: "140px",
                display: "flex",
                flexDirection: "column",
                justifyContent: "space-between",
              }}
            >
              <div>
                <div
                  style={{
                    fontSize: "clamp(0.625rem, 2.5vw, 0.75rem)",
                    color: "rgba(255,255,255,0.9)",
                    marginBottom: 8,
                    fontWeight: 600,
                    letterSpacing: "0.5px",
                  }}
                >
                  WORSHIP LIST
                </div>
                <div
                  style={{
                    fontWeight: "bold",
                    fontSize: "clamp(1rem, 4vw, 1.25rem)",
                    color: "white",
                    marginBottom: 8,
                  }}
                >
                  {(() => {
                    const [year, month, day] = p.date.split("-");
                    return new Date(year, month - 1, day).toLocaleDateString(
                      "en-US",
                      {
                        weekday: "short",
                        month: "short",
                        day: "numeric",
                        year: "numeric",
                      }
                    );
                  })()}
                </div>
              </div>
              <div
                style={{
                  fontSize: "clamp(0.75rem, 3vw, 0.8125rem)",
                  color: "rgba(255,255,255,0.85)",
                }}
              >
                {p.songs && p.songs.length > 0
                  ? `${p.songs.length} songs`
                  : "No songs added"}
                {p.notes && " • Notes available"}
              </div>
            </div>
          ))}
        </div>
      </div>

      {/* Search Songs Section */}
      <div className="bg-white p-3 sm:p-4 md:p-5 rounded-xl shadow-md mb-6 border border-gray-200">
        <h3
          className="text-xl font-bold text-gray-800 mb-4 flex items-center gap-2"
          style={{ fontSize: "clamp(1.125rem, 4vw, 1.25rem)" }}
        >
          <span>🔍</span> Search Songs
        </h3>
        <div className="flex gap-2 sm:gap-3 flex-wrap">
          <input
            value={q}
            onChange={(e) => {
              const v = e.target.value;
              setQ(v);
              if (v.trim() === "") {
                // Clear results & errors when search box emptied
                setResults([]);
                setError(null);
              }
            }}
            onKeyPress={(e) => e.key === "Enter" && doSearch()}
            type="text"
            placeholder="Search songs, artists, or bands..."
            className="flex-1 w-full sm:min-w-[250px] px-3 sm:px-4 py-2.5 border-2 border-gray-300 rounded-lg focus:outline-none focus:border-purple-500 focus:ring-2 focus:ring-purple-200 transition-all"
            style={{ fontSize: "16px", WebkitTextSizeAdjust: "100%" }}
          />
          <select
            value={filterType}
            onChange={(e) => setFilterType(e.target.value)}
            className="w-full sm:w-auto px-3 sm:px-4 py-2.5 border-2 border-gray-300 rounded-lg focus:outline-none focus:border-purple-500 focus:ring-2 focus:ring-purple-200 bg-white transition-all sm:min-w-[140px]"
            style={{ fontSize: "16px", WebkitTextSizeAdjust: "100%" }}
          >
            <option value="all">All Types</option>
            <option value="title">Title</option>
            <option value="artist">Artist</option>
            <option value="band">Band</option>
          </select>
          <button
            onClick={() => {
              const term = encodeURIComponent(q.trim());
              if (!term) {
                setError("Please enter a search term");
                return;
              }
              const links = [
                `https://www.google.com/search?q=${term}+lyrics`,
                `https://www.bing.com/search?q=${term}+lyrics`,
                `https://duckduckgo.com/?q=${term}+lyrics`,
                `https://worship.lifeway.com/findAndBuy/home?findMappable=false&searchString=${term}`,
              ];
              links.forEach((u) => window.open(u, "_blank"));
            }}
            className="px-6 py-2.5 text-white rounded-lg font-semibold transition-all whitespace-nowrap bg-gradient-to-r from-blue-600 to-blue-700 hover:from-blue-700 hover:to-blue-800 shadow-md hover:shadow-lg"
          >
            🌎 Scan Web
          </button>
          <button
            onClick={doSearch}
            disabled={searching}
            className={`px-6 py-2.5 text-white rounded-lg font-semibold transition-all whitespace-nowrap ${
              searching
                ? "bg-gray-400 cursor-not-allowed"
                : "bg-gradient-to-r from-green-600 to-green-700 hover:from-green-700 hover:to-green-800 shadow-md hover:shadow-lg"
            }`}
          >
            {searching ? "🔄 Searching..." : "🌐 Search"}
          </button>
        </div>
        {error && (
          <div className="p-3 bg-red-50 text-red-700 rounded-lg mt-3 font-medium">
            ⚠️ {error}
          </div>
        )}
        {!error && q.trim() === "" && (
          <div className="p-3 bg-purple-50 text-purple-700 rounded-lg mt-3 text-sm">
            Type above to search. Results will appear automatically.
          </div>
        )}
        <div className="mt-5 border-t border-gray-200 pt-4">
          <h4 className="m-0 mb-2 text-lg font-semibold">Upload Lyric File</h4>
          <div
            style={{
              display: "flex",
              gap: 12,
              alignItems: "center",
              flexWrap: "wrap",
            }}
          >
            <input
              type="file"
              onChange={(e) => {
                setUploadFile(e.target.files[0]);
                setUploadError(null);
              }}
              className="flex-1"
            />
            <button
              onClick={handleUpload}
              disabled={!uploadFile || uploading}
              className={`px-5 py-2.5 text-white rounded-lg font-bold transition-colors ${
                uploading
                  ? "bg-gray-400 cursor-not-allowed"
                  : "bg-purple-700 hover:bg-purple-800 cursor-pointer"
              }`}
            >
              {uploading ? "Uploading..." : "Extract"}
            </button>
            {uploadFile && (
              <button
                onClick={handleUpload}
                disabled={uploading}
                className={`px-5 py-2.5 text-white rounded-lg font-bold transition-colors ${
                  uploading
                    ? "bg-gray-400 cursor-not-allowed"
                    : "bg-green-600 hover:bg-green-700 cursor-pointer"
                }`}
              >
                View & Edit
              </button>
            )}
          </div>
          {uploadError && (
            <div className="mt-2 p-2.5 bg-yellow-100 text-yellow-800 rounded-lg">
              ⚠️ {uploadError}
            </div>
          )}
          {uploadFile && !uploadError && (
            <div className="mt-2 text-xs text-gray-600">
              Selected: {uploadFile.name}
            </div>
          )}
          <div className="mt-2 text-[11px] text-gray-500">
            Supported: .txt .docx .pdf .png .jpg .jpeg (image OCR requires
            Tesseract installed)
          </div>
        </div>

        {/* Create Blank Sheet Section */}
        <div className="border-t border-gray-200 pt-4 mt-4">
          <h4 style={{ margin: 0, marginBottom: 8 }}>Create Blank Sheet</h4>
          <p
            style={{ margin: 0, marginBottom: 12, fontSize: 13, color: "#666" }}
          >
            Create a blank lyric sheet to manually enter or paste song lyrics
          </p>
          <button
            onClick={createBlankSheet}
            className="px-5 py-2.5 bg-blue-600 text-white rounded-lg font-bold hover:bg-blue-700 transition-colors cursor-pointer"
          >
            📄 Create Blank Sheet
          </button>
        </div>
      </div>

      {results.length > 0 && (
        <div className="mb-6 px-2 sm:px-0">
          <h3
            className="mb-3 text-xl sm:text-2xl font-bold text-gray-800"
            style={{ fontSize: "clamp(1.125rem, 4vw, 1.5rem)" }}
          >
            Search Results ({results.length})
          </h3>
          {results.map((r, i) => (
            <div
              key={i}
              className="border border-gray-200 p-3 sm:p-4 mb-3 rounded-lg bg-white relative hover:shadow-md transition-shadow"
            >
              {r.source && (
                <div
                  className={`absolute top-2 right-2 px-2 py-1 text-white text-[10px] sm:text-[11px] rounded font-bold ${
                    r.source === "local_db"
                      ? "bg-green-600"
                      : r.source === "genius"
                      ? "bg-red-700"
                      : r.source === "lifeway"
                      ? "bg-purple-700"
                      : "bg-orange-500"
                  }`}
                >
                  {r.source === "local_db"
                    ? "📁 Local"
                    : r.source === "genius"
                    ? "🎤 Genius"
                    : r.source === "lifeway"
                    ? "🎵 Lifeway"
                    : "🌐 Web"}
                </div>
              )}
              <div
                className="font-bold mb-1 pr-16 sm:pr-20"
                style={{ fontSize: "clamp(1rem, 4vw, 1.125rem)" }}
              >
                {r.title}
              </div>
              <div
                className="text-gray-600 mb-2"
                style={{ fontSize: "clamp(0.875rem, 3.5vw, 1rem)" }}
              >
                {r.artist} — {r.band}
              </div>
              <div
                className="text-gray-500 mb-3 leading-relaxed"
                style={{ fontSize: "clamp(0.75rem, 3vw, 0.875rem)" }}
              >
                {r.snippet}
              </div>
              {r.url ? (
                <a
                  href={r.url}
                  target="_blank"
                  rel="noreferrer"
                  className="no-underline inline-block"
                >
                  <button
                    className={`px-3 py-2 sm:px-4 sm:py-2 text-white rounded-md cursor-pointer hover:opacity-90 transition-opacity ${
                      r.source === "genius" ? "bg-red-700" : "bg-purple-700"
                    }`}
                    style={{ fontSize: "clamp(0.875rem, 3.5vw, 1rem)" }}
                  >
                    {r.source === "genius"
                      ? "Open on Genius"
                      : "Open on Lifeway"}
                  </button>
                </a>
              ) : (
                <button
                  onClick={() => openPreview(r)}
                  className="px-3 py-2 sm:px-4 sm:py-2 bg-blue-600 text-white rounded-md cursor-pointer hover:bg-blue-700 transition-colors"
                  style={{ fontSize: "clamp(0.875rem, 3.5vw, 1rem)" }}
                >
                  Preview & Save
                </button>
              )}
            </div>
          ))}
        </div>
      )}

      {showCreateDay && (
        <div
          onClick={closePlanModal}
          style={{
            position: "fixed",
            inset: 0,
            background: "rgba(0,0,0,0.6)",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            zIndex: 10000,
            overflow: "auto",
            padding: "12px",
          }}
        >
          <div
            onClick={(e) => e.stopPropagation()}
            className="bg-white p-4 sm:p-6 md:p-8 rounded-2xl w-full shadow-2xl"
            style={{
              maxWidth: 900,
              maxHeight: "90vh",
              overflow: "auto",
            }}
          >
            <h2 className="text-2xl font-bold mb-6 text-gray-800">
              {editingPlan ? "Edit Worship List" : "Create Worship List"}
            </h2>

            {/* Date Selector */}
            <div className="mb-6">
              <label className="block text-sm font-semibold text-gray-700 mb-2">
                Worship Date *
              </label>
              <input
                type="date"
                value={newDate}
                onChange={(e) => setNewDate(e.target.value)}
                onClick={(e) => e.target.showPicker && e.target.showPicker()}
                className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent cursor-pointer"
                required
              />
            </div>

            {/* Notes Section */}
            <div className="mb-6">
              <label className="block text-sm font-semibold text-gray-700 mb-2">
                Notes / Memo
              </label>
              <textarea
                value={planNotes}
                onChange={(e) => setPlanNotes(e.target.value)}
                className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent resize-y"
                rows={3}
                placeholder="Add planning notes, announcements, special instructions..."
              />
            </div>

            {/* Song Search Section */}
            <div className="mb-6">
              <label className="block text-sm font-semibold text-gray-700 mb-2">
                Search & Add Songs
              </label>
              <input
                type="text"
                value={planSongSearch}
                onChange={(e) => setPlanSongSearch(e.target.value)}
                className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent mb-3"
                placeholder="Search by title, artist, or band..."
              />
              <div className="max-h-64 overflow-y-auto border border-gray-200 rounded-lg bg-white">
                {planSearchResults.length > 0
                  ? planSearchResults.map((song) => {
                      const isAdded = chosenSongs.find((s) => s.id === song.id);
                      return (
                        <div
                          key={song.id}
                          className={`p-3 border-b border-gray-100 flex justify-between items-center transition-all ${
                            isAdded ? "bg-green-50" : "hover:bg-purple-50"
                          }`}
                        >
                          <div className="flex-1">
                            <div className="font-semibold text-sm text-gray-800">
                              {song.title}
                            </div>
                            <div className="text-xs text-gray-600">
                              {song.artist || song.band}
                              {song.singer && (
                                <span className="ml-2 text-purple-600">
                                  🎤 {song.singer}
                                </span>
                              )}
                            </div>
                          </div>
                          {isAdded ? (
                            <div className="ml-3 px-4 py-2 bg-green-500 text-white text-xs font-semibold rounded flex items-center gap-1 flex-shrink-0">
                              <span>✓</span> Added
                            </div>
                          ) : (
                            <button
                              onClick={() => addSongToChosen(song)}
                              className="ml-3 px-4 py-2 bg-purple-600 text-white text-xs font-semibold rounded hover:bg-purple-700 transition-colors flex-shrink-0"
                            >
                              Add
                            </button>
                          )}
                        </div>
                      );
                    })
                  : null}
              </div>
            </div>

            {/* Chosen Songs with Ordering */}
            <div className="mb-6">
              <label className="block text-sm font-semibold text-gray-700 mb-2">
                Selected Songs ({chosenSongs.length})
              </label>
              <div className="border border-gray-300 rounded-lg p-4 bg-gray-50 min-h-32">
                {chosenSongs.length > 0 ? (
                  <div className="space-y-2">
                    {chosenSongs.map((song, idx) => (
                      <div
                        key={song.id}
                        draggable
                        onDragStart={(e) => handleDragStart(e, idx)}
                        onDragEnd={handleDragEnd}
                        onDragOver={handleDragOver}
                        onDrop={(e) => handleDrop(e, idx)}
                        onTouchStart={(e) => handleTouchStart(e, idx)}
                        onTouchMove={handleTouchMove}
                        onTouchEnd={(e) => handleTouchEnd(e, idx)}
                        className={`flex items-center gap-3 bg-white p-3 rounded-lg shadow-sm cursor-move transition-all ${
                          draggedSongIndex === idx
                            ? "opacity-50 scale-95"
                            : "hover:shadow-md"
                        }`}
                      >
                        <div
                          className="flex items-center text-gray-400 hover:text-purple-600 cursor-grab active:cursor-grabbing touch-none select-none"
                          title="Drag to reorder"
                        >
                          <svg
                            className="w-5 h-5"
                            fill="currentColor"
                            viewBox="0 0 20 20"
                          >
                            <path d="M7 2a2 2 0 1 0 .001 4.001A2 2 0 0 0 7 2zm0 6a2 2 0 1 0 .001 4.001A2 2 0 0 0 7 8zm0 6a2 2 0 1 0 .001 4.001A2 2 0 0 0 7 14zm6-8a2 2 0 1 0-.001-4.001A2 2 0 0 0 13 6zm0 2a2 2 0 1 0 .001 4.001A2 2 0 0 0 13 8zm0 6a2 2 0 1 0 .001 4.001A2 2 0 0 0 13 14z" />
                          </svg>
                        </div>
                        <div className="flex-1">
                          <div className="font-semibold text-sm text-gray-800">
                            {idx + 1}. {song.title}
                          </div>
                          <div className="text-xs text-gray-600">
                            {song.artist || song.band}
                          </div>
                        </div>
                        <button
                          onClick={() => removeSongFromChosen(song.id)}
                          className="text-red-600 hover:text-red-700 font-bold text-lg px-2"
                          title="Remove"
                        >
                          ×
                        </button>
                      </div>
                    ))}
                  </div>
                ) : (
                  <div className="text-center text-gray-500 text-sm py-8">
                    No songs selected yet. Add songs from the search above.
                  </div>
                )}
              </div>
            </div>

            {/* Action Buttons */}
            <div className="flex gap-3 justify-end pt-4 border-t border-gray-200">
              <button
                onClick={closePlanModal}
                className="px-6 py-3 bg-gray-500 text-white rounded-lg hover:bg-gray-600 transition-colors font-semibold"
              >
                Cancel
              </button>
              <button
                onClick={createNewDay}
                disabled={!newDate}
                className="px-6 py-3 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition-colors font-semibold disabled:bg-gray-300 disabled:cursor-not-allowed"
              >
                {editingPlan ? "Update List" : "Create List"}
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Sheet View Modal */}
      {viewingPlan && (
        <div
          onClick={() => setViewingPlan(null)}
          style={{
            position: "fixed",
            inset: 0,
            background: "rgba(0,0,0,0.7)",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            zIndex: 10000,
            overflow: "auto",
            padding: "12px",
          }}
        >
          <div
            onClick={(e) => e.stopPropagation()}
            className="bg-white p-4 sm:p-6 md:p-10 rounded-2xl w-full shadow-2xl"
            style={{
              maxWidth: 700,
              maxHeight: "90vh",
              overflow: "auto",
            }}
          >
            <div className="flex justify-between items-start mb-6">
              <div>
                <h2 className="text-3xl font-bold text-gray-800 mb-2">
                  Worship List
                </h2>
                <div className="text-xl text-purple-600 font-semibold">
                  {(() => {
                    const [year, month, day] = viewingPlan.date.split("-");
                    return new Date(year, month - 1, day).toLocaleDateString(
                      "en-US",
                      {
                        weekday: "long",
                        month: "long",
                        day: "numeric",
                        year: "numeric",
                      }
                    );
                  })()}
                </div>
              </div>
              <button
                onClick={() => setViewingPlan(null)}
                aria-label="Close worship list"
                className="text-gray-500 hover:text-gray-700 text-2xl font-bold"
              >
                ×
              </button>
            </div>

            {/* Notes Section */}
            {viewingPlan.notes && (
              <div className="mb-6 p-4 bg-yellow-50 border-l-4 border-yellow-400 rounded">
                <h3 className="text-sm font-semibold text-gray-700 mb-2">
                  Notes
                </h3>
                <p className="text-gray-700 whitespace-pre-wrap">
                  {viewingPlan.notes}
                </p>
              </div>
            )}

            {/* Song Lineup */}
            <div className="mb-6">
              <h3 className="text-lg font-semibold text-gray-800 mb-4">
                Song Lineup
              </h3>
              {viewingPlan.songs && viewingPlan.songs.length > 0 ? (
                <div className="space-y-3" role="list">
                  {viewingPlan.songs.map((song, idx) => {
                    const songTitle =
                      song?.title || song?.name || "Untitled Song";
                    const songArtist =
                      song?.artist || song?.band || song?.singer || "";

                    return (
                      <div
                        key={song?.id || idx}
                        role="listitem"
                        onClick={async () => {
                          if (song?.id) {
                            const fullSong = await getSongMerged(song.id);
                            setViewingPlanSong(fullSong);
                          }
                        }}
                        onKeyPress={async (e) => {
                          if (e.key === "Enter" || e.key === " ") {
                            e.preventDefault();
                            if (song?.id) {
                              const fullSong = await getSongMerged(song.id);
                              setViewingPlanSong(fullSong);
                            }
                          }
                        }}
                        tabIndex={0}
                        aria-label={`Song ${idx + 1}: ${songTitle}${
                          songArtist ? ` by ${songArtist}` : ""
                        }`}
                        className="flex items-center gap-3 p-3 sm:p-4 bg-gradient-to-r from-purple-50 to-blue-50 rounded-lg border border-purple-200 cursor-pointer hover:border-purple-400 hover:shadow-lg transition-all focus:outline-none focus:ring-2 focus:ring-purple-500"
                      >
                        <div className="flex items-center justify-center w-8 h-8 sm:w-10 sm:h-10 bg-purple-600 text-white rounded-full font-bold text-base sm:text-lg flex-shrink-0">
                          {idx + 1}
                        </div>
                        <div className="flex-1 min-w-0">
                          <div
                            className="font-bold text-gray-800 break-words"
                            style={{ fontSize: "clamp(1rem, 4vw, 1.125rem)" }}
                          >
                            {songTitle}
                          </div>
                          {songArtist && (
                            <div
                              className="text-gray-600 truncate"
                              style={{
                                fontSize: "clamp(0.75rem, 3vw, 0.875rem)",
                              }}
                            >
                              {songArtist}
                            </div>
                          )}
                        </div>
                        <div className="hidden sm:block text-sm text-purple-600 font-semibold flex-shrink-0">
                          Click to view →
                        </div>
                        <div className="sm:hidden text-purple-600 flex-shrink-0">
                          <svg
                            className="w-5 h-5"
                            fill="none"
                            stroke="currentColor"
                            viewBox="0 0 24 24"
                          >
                            <path
                              strokeLinecap="round"
                              strokeLinejoin="round"
                              strokeWidth={2}
                              d="M9 5l7 7-7 7"
                            />
                          </svg>
                        </div>
                      </div>
                    );
                  })}
                </div>
              ) : (
                <div className="text-center text-gray-500 py-8 bg-gray-50 rounded-lg">
                  No songs added to this worship list
                </div>
              )}
            </div>

            {/* Action Buttons */}
            <div className="flex gap-3 justify-end pt-4 border-t border-gray-200">
              <button
                onClick={() => openEditPlan(viewingPlan)}
                className="px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-semibold flex items-center gap-2"
              >
                <span>✏️</span>
                Edit List
              </button>
              <button
                onClick={() => setDeleteConfirmPlan(viewingPlan)}
                className="px-6 py-3 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors font-semibold flex items-center gap-2"
              >
                <span>🗑️</span>
                Delete List
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Delete Confirmation Modal */}
      {deleteConfirmPlan && (
        <div
          onClick={() => setDeleteConfirmPlan(null)}
          style={{
            position: "fixed",
            inset: 0,
            background: "rgba(0,0,0,0.7)",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            zIndex: 10000,
          }}
        >
          <div
            onClick={(e) => e.stopPropagation()}
            className="bg-white p-8 rounded-xl shadow-2xl max-w-md"
          >
            <h3 className="text-xl font-bold text-gray-800 mb-4">
              Confirm Delete
            </h3>
            <p className="text-gray-600 mb-6">
              Are you sure you want to delete the worship list for{" "}
              <span className="font-semibold">
                {(() => {
                  const [year, month, day] = deleteConfirmPlan.date.split("-");
                  return new Date(year, month - 1, day).toLocaleDateString();
                })()}
              </span>
              ? This action cannot be undone.
            </p>
            <div className="flex gap-3 justify-end">
              <button
                onClick={() => setDeleteConfirmPlan(null)}
                className="px-6 py-2 bg-gray-500 text-white rounded-lg hover:bg-gray-600 transition-colors font-semibold"
              >
                No, Cancel
              </button>
              <button
                onClick={() => handleDeletePlan(deleteConfirmPlan.id)}
                className="px-6 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors font-semibold"
              >
                Yes, Delete
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Worship List Song Sheet View */}
      {viewingPlanSong && (
        <div
          onClick={() => setViewingPlanSong(null)}
          style={{
            position: "fixed",
            inset: 0,
            background: "rgba(0,0,0,0.8)",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            zIndex: 10001,
            overflow: "auto",
            padding: "12px",
          }}
        >
          <div
            onClick={(e) => e.stopPropagation()}
            className="bg-white p-4 sm:p-6 md:p-10 rounded-2xl w-full shadow-2xl"
            style={{
              maxWidth: 900,
              maxHeight: "90vh",
              overflow: "auto",
            }}
          >
            {/* Navigation Buttons */}
            {viewingPlan &&
              viewingPlan.songs &&
              viewingPlan.songs.length > 1 && (
                <div className="flex justify-center items-center gap-3 mb-6">
                  <button
                    onClick={navigateToPrevSong}
                    disabled={
                      viewingPlan.songs.findIndex(
                        (s) => s.id === viewingPlanSong.id
                      ) === 0
                    }
                    className="flex items-center gap-2 px-6 py-3 bg-gradient-to-r from-blue-500 to-blue-600 text-white rounded-lg font-semibold shadow-lg hover:from-blue-600 hover:to-blue-700 disabled:from-gray-300 disabled:to-gray-400 disabled:cursor-not-allowed transition-all transform hover:scale-105 active:scale-95"
                  >
                    <svg
                      className="w-5 h-5"
                      fill="none"
                      stroke="currentColor"
                      viewBox="0 0 24 24"
                    >
                      <path
                        strokeLinecap="round"
                        strokeLinejoin="round"
                        strokeWidth={2}
                        d="M15 19l-7-7 7-7"
                      />
                    </svg>
                    <span>Back</span>
                  </button>

                  <div className="px-4 py-2 bg-gray-100 rounded-lg text-sm font-semibold text-gray-700">
                    {viewingPlan.songs.findIndex(
                      (s) => s.id === viewingPlanSong.id
                    ) + 1}{" "}
                    / {viewingPlan.songs.length}
                  </div>

                  <button
                    onClick={navigateToNextSong}
                    disabled={
                      viewingPlan.songs.findIndex(
                        (s) => s.id === viewingPlanSong.id
                      ) ===
                      viewingPlan.songs.length - 1
                    }
                    className="flex items-center gap-2 px-6 py-3 bg-gradient-to-r from-blue-500 to-blue-600 text-white rounded-lg font-semibold shadow-lg hover:from-blue-600 hover:to-blue-700 disabled:from-gray-300 disabled:to-gray-400 disabled:cursor-not-allowed transition-all transform hover:scale-105 active:scale-95"
                  >
                    <span>Next</span>
                    <svg
                      className="w-5 h-5"
                      fill="none"
                      stroke="currentColor"
                      viewBox="0 0 24 24"
                    >
                      <path
                        strokeLinecap="round"
                        strokeLinejoin="round"
                        strokeWidth={2}
                        d="M9 5l7 7-7 7"
                      />
                    </svg>
                  </button>
                </div>
              )}

            <div className="flex justify-between items-start mb-6">
              <div>
                <h2 className="text-3xl font-bold text-gray-800 mb-2">
                  {viewingPlanSong.title}
                </h2>
                <p className="text-lg text-gray-600">
                  {viewingPlanSong.artist || viewingPlanSong.band}
                </p>
              </div>
              <button
                onClick={() => setViewingPlanSong(null)}
                className="text-gray-500 hover:text-gray-700 text-3xl font-bold"
              >
                ×
              </button>
            </div>

            {/* Embedded LyricModal Content */}
            <LyricModal
              modal={viewingPlanSong}
              setModal={setViewingPlanSong}
              onSave={async () => {
                await saveSong(viewingPlanSong.id, {
                  title: viewingPlanSong.title,
                  artist: viewingPlanSong.artist,
                  band: viewingPlanSong.band,
                  lyrics: viewingPlanSong.lyrics,
                  chords: viewingPlanSong.chords,
                  singer: viewingPlanSong.singer,
                });
                await loadPlans();
                // Trigger sync events for both songs and plans
                window.dispatchEvent(
                  new CustomEvent("songsChanged", {
                    detail: { id: viewingPlanSong.id },
                  })
                );
                window.dispatchEvent(new Event("plansChanged"));
              }}
              profileKey={
                profiles.find((p) => p.id == selectedProfile)?.default_key
              }
              profileId={selectedProfile}
              viewingPlan={viewingPlan}
              onNavigateNext={navigateToNextSong}
              onNavigatePrev={navigateToPrevSong}
            />

            {/* Back Button */}
            <div className="mt-6 pt-6 border-t border-gray-200">
              <button
                onClick={() => setViewingPlanSong(null)}
                className="px-6 py-3 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition-colors font-semibold flex items-center gap-2"
              >
                ← Back to Worship List
              </button>
            </div>
          </div>
        </div>
      )}

      {modal && (
        <div
          onTouchStart={onTouchStart}
          onTouchMove={onTouchMove}
          onTouchEnd={onTouchEnd}
        >
          <LyricModal
            modal={modal}
            setModal={closeModal}
            onSave={saveToDatabase}
            profileKey={
              profiles.find((p) => p.id == selectedProfile)?.default_key
            }
            profileId={selectedProfile}
          />
        </div>
      )}
    </main>
  );
}

function Profile() {
  const location = useLocation();
  const navigate = useNavigate();
  const isMobile = useIsMobile();

  // Read profile ID from URL - this is the ONLY source of truth
  const urlParams = new URLSearchParams(location.search);
  const viewingProfileId = urlParams.get("id");

  const [profiles, setProfiles] = useState([]);
  const [editing, setEditing] = useState(null);
  const [firstName, setFirstName] = useState("");
  const [lastName, setLastName] = useState("");
  const [email, setEmail] = useState("");
  const [contactNumber, setContactNumber] = useState("");
  const [notes, setNotes] = useState("");
  const [profileSearchQ, setProfileSearchQ] = useState("");
  const [allSongsSearchQ, setAllSongsSearchQ] = useState("");
  const [savedSongsSearchQ, setSavedSongsSearchQ] = useState("");
  const [allSongs, setAllSongs] = useState([]);
  const [profileSongs, setProfileSongs] = useState([]);
  const [modal, setModal] = useState(null);
  const [deleteConfirmProfile, setDeleteConfirmProfile] = useState(null);
  const [addingAnimations, setAddingAnimations] = useState({}); // Track songs being added with animation
  const [loadingProfiles, setLoadingProfiles] = useState(false);
  const [loadingProfileSongs, setLoadingProfileSongs] = useState(false);

  // Ref to track if we've loaded profiles to prevent duplicate fetches
  const profilesLoadedRef = React.useRef(false);
  const loadingProfilesRef = React.useRef(false);

  // Load profiles once on mount
  useEffect(() => {
    if (!profilesLoadedRef.current) {
      loadProfiles();
    }
  }, []);

  // Load profile songs when viewing profile ID changes
  useEffect(() => {
    if (viewingProfileId) {
      loadProfileSongs(viewingProfileId);
    } else {
      setProfileSongs([]);
    }
  }, [viewingProfileId]);

  // Listen for external profile/song changes
  useEffect(() => {
    const handleProfileChange = () => {
      loadProfiles();
    };
    const handleSongsChange = () => {
      if (viewingProfileId) {
        loadProfileSongs(viewingProfileId);
      }
    };
    const handleProfileSongsChange = (event) => {
      if (
        viewingProfileId &&
        event.detail?.profile_id?.toString() === viewingProfileId
      ) {
        loadProfileSongs(viewingProfileId);
      }
    };

    window.addEventListener("profileChanged", handleProfileChange);
    window.addEventListener("songsChanged", handleSongsChange);
    window.addEventListener("profileSongsChanged", handleProfileSongsChange);

    return () => {
      window.removeEventListener("profileChanged", handleProfileChange);
      window.removeEventListener("songsChanged", handleSongsChange);
      window.removeEventListener(
        "profileSongsChanged",
        handleProfileSongsChange
      );
    };
  }, [viewingProfileId]);

  async function loadProfiles() {
    if (loadingProfilesRef.current) return; // Prevent concurrent fetches
    loadingProfilesRef.current = true;
    setLoadingProfiles(true);
    try {
      const p = await fetchProfiles();
      setProfiles(p || []);
      profilesLoadedRef.current = true;
    } catch (err) {
      console.error("[Profile.loadProfiles] Error loading profiles:", err);
      // Try localStorage fallback
      try {
        const localProfiles = await localStorageAPI.getProfiles();
        setProfiles(localProfiles || []);
        profilesLoadedRef.current = true;
      } catch (fallbackErr) {
        console.error(
          "[Profile.loadProfiles] Fallback also failed:",
          fallbackErr
        );
        setProfiles([]);
      }
    } finally {
      setLoadingProfiles(false);
      loadingProfilesRef.current = false;
    }
  }

  async function loadAllSongs(query = "") {
    if (!query.trim()) {
      setAllSongs([]);
      return;
    }
    const s = await searchLocalSongs(query);
    const validSongs = (s || []).filter(
      (song) =>
        song.title &&
        song.title.trim() !== "" &&
        song.title.trim().toLowerCase() !== "untitled"
    );
    setAllSongs(validSongs);
  }

  async function loadProfileSongs(profileId) {
    setLoadingProfileSongs(true);

    try {
      const songs = await getProfileSongs(profileId);
      setProfileSongs(songs || []);
    } catch (err) {
      console.error(
        "[Profile.loadProfileSongs] Error loading profile songs:",
        err
      );
      setProfileSongs([]);
    } finally {
      setLoadingProfileSongs(false);
    }
  }

  async function saveProfile() {
    const fullName = `${firstName} ${lastName}`.trim();
    if (editing) {
      await updateProfile(editing, {
        name: fullName,
        email,
        contact_number: contactNumber,
        notes,
      });
    } else {
      await createProfile({
        name: fullName,
        email,
        contact_number: contactNumber,
        notes,
      });
    }
    await loadProfiles();
    window.dispatchEvent(new Event("profileChanged"));
    clearForm();
  }

  function clearForm() {
    setEditing(null);
    setFirstName("");
    setLastName("");
    setEmail("");
    setContactNumber("");
    setNotes("");
  }

  function editProfile(p) {
    setEditing(p.id);
    const nameParts = (p?.name || "").split(" ");
    setFirstName(nameParts[0] || "");
    setLastName(nameParts.slice(1).join(" ") || "");
    setEmail(p?.email || "");
    setContactNumber(p?.contact_number || "");
    setNotes(p?.notes || "");
  }

  function viewProfile(profileId) {
    // Update URL using React Router - this will trigger Profile component to re-render with new ID
    navigate(`/profile?id=${profileId}`);
  }

  function backToManagement() {
    // Update URL using React Router
    navigate("/profile");

    // Clear search states
    setAllSongsSearchQ("");
    setSavedSongsSearchQ("");

    // Broadcast to all devices via backend (non-blocking)
    clearProfileSelection().catch(() => {
      // Silent fail
    });
  }

  async function addSongToUserProfile(song) {
    if (!viewingProfileId) return;

    // Start animation
    setAddingAnimations((prev) => ({ ...prev, [song.id]: true }));

    // Add to profile
    await addSongToProfile(viewingProfileId, song.id);
    await loadProfileSongs(viewingProfileId);

    // Keep animation for a bit then remove
    setTimeout(() => {
      setAddingAnimations((prev) => {
        const newState = { ...prev };
        delete newState[song.id];
        return newState;
      });
    }, 600); // Animation duration

    // Trigger sync event for other components/devices
    window.dispatchEvent(
      new CustomEvent("profileSongsChanged", {
        detail: { profile_id: viewingProfileId },
      })
    );
  }

  async function removeSongFromUserProfile(songId) {
    if (!viewingProfileId) return;
    await removeSongFromProfile(viewingProfileId, songId);
    await loadProfileSongs(viewingProfileId);
    // Trigger sync event for other components/devices
    window.dispatchEvent(
      new CustomEvent("profileSongsChanged", {
        detail: { profile_id: viewingProfileId },
      })
    );
  }

  async function openSong(s) {
    const full = await getSong(s.id);
    if (isMobile) {
      navigate("/view-profile-song", { state: { song: full } });
    } else {
      setModal(full);
    }
  }

  async function handleDeleteProfile(profileId) {
    if (!deleteConfirmProfile) return;
    await deleteProfile(profileId);
    await loadProfiles();
    window.dispatchEvent(new Event("profileChanged"));
    setDeleteConfirmProfile(null);
  }

  const filteredProfiles = profiles.filter(
    (p) =>
      p.name?.toLowerCase().includes(profileSearchQ.toLowerCase()) ||
      p.email?.toLowerCase().includes(profileSearchQ.toLowerCase())
  );

  const filteredAllSongs = allSongs.filter(
    (s) =>
      s.title?.toLowerCase().includes(allSongsSearchQ.toLowerCase()) ||
      s.artist?.toLowerCase().includes(allSongsSearchQ.toLowerCase()) ||
      s.band?.toLowerCase().includes(allSongsSearchQ.toLowerCase()) ||
      s.singer?.toLowerCase().includes(allSongsSearchQ.toLowerCase())
  );

  const filteredSavedSongs = profileSongs.filter(
    (s) =>
      s.title?.toLowerCase().includes(savedSongsSearchQ.toLowerCase()) ||
      s.artist?.toLowerCase().includes(savedSongsSearchQ.toLowerCase()) ||
      s.band?.toLowerCase().includes(savedSongsSearchQ.toLowerCase()) ||
      s.singer?.toLowerCase().includes(savedSongsSearchQ.toLowerCase()) ||
      s.lyrics?.toLowerCase().includes(savedSongsSearchQ.toLowerCase())
  );

  // User Profile View
  if (viewingProfileId) {
    const profile = profiles.find(
      (p) =>
        p.id == viewingProfileId ||
        p.id?.toString() === viewingProfileId?.toString()
    );

    return (
      <div
        className="p-3 md:p-8 overflow-x-hidden"
        style={{ width: "100%", maxWidth: "100vw", boxSizing: "border-box" }}
      >
        {/* Show not found message without unmounting */}
        {!profile && !loadingProfiles ? (
          <div className="max-w-2xl mx-auto text-center">
            <h2 className="text-2xl font-bold text-gray-800 mb-4">
              Profile not found
            </h2>
            <p className="text-gray-600 mb-6">
              The profile you're looking for doesn't exist or has been deleted.
            </p>
            <button
              onClick={backToManagement}
              className="px-6 py-3 bg-purple-600 text-white rounded-lg hover:bg-gray-700 transition-colors font-semibold"
            >
              ← Back to Profile Management
            </button>
          </div>
        ) : profile ? (
          <>
            {/* Header */}
            <div className="max-w-7xl mx-auto mb-8 flex flex-col md:flex-row justify-between items-start md:items-center gap-4">
              <div>
                <h1 className="text-4xl font-bold text-gray-800 mb-2">
                  Hello, {(profile?.name || "User").split(" ")[0]} — Welcome
                  Back! 👋
                </h1>
                <p className="text-gray-600">
                  Manage your personal song collection
                </p>
              </div>
              <button
                onClick={backToManagement}
                className="px-6 py-3 bg-gray-600 text-white rounded-lg hover:bg-gray-700 transition-colors font-semibold"
              >
                ← Back to Management
              </button>
            </div>

            {/* Search All Songs Section */}
            <div className="max-w-7xl mx-auto mb-8 p-6 bg-gradient-to-r from-purple-50 to-blue-50 rounded-xl border border-purple-200">
              <h3 className="text-xl font-bold text-gray-800 mb-4">
                🔍 Search All Songs
              </h3>
              <input
                value={allSongsSearchQ}
                onChange={(e) => {
                  const v = e.target.value;
                  setAllSongsSearchQ(v);
                  loadAllSongs(v);
                }}
                placeholder="Search by title, artist, band, or singer..."
                className="w-full p-4 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500 mb-4"
              />
              {/* Removed max-h-96 overflow-y-auto for mobile - no nested scroll */}
              <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                {filteredAllSongs.length > 0 ? (
                  filteredAllSongs.map((song) => {
                    const alreadyAdded = profileSongs.some(
                      (ps) => ps.id === song.id
                    );
                    const isAnimating = addingAnimations[song.id];

                    // Hide song if already added and not animating
                    if (alreadyAdded && !isAnimating) {
                      return null;
                    }

                    return (
                      <div
                        key={song.id}
                        className={`bg-white p-4 rounded-lg border border-gray-200 hover:shadow-md transition-all duration-500 ${
                          isAnimating
                            ? "opacity-0 scale-75"
                            : "opacity-100 scale-100"
                        }`}
                      >
                        <div className="font-bold text-gray-800 mb-1">
                          {song.title}
                        </div>
                        <div className="flex items-center justify-between gap-2 mb-2">
                          <div className="flex-1">
                            {song.singer && (
                              <div className="text-sm text-purple-600 font-semibold">
                                🎤 {song.singer}
                              </div>
                            )}
                          </div>
                          {song.chords && (
                            <div className="flex-shrink-0">
                              <span className="inline-block px-2 py-1 text-xs font-bold bg-blue-100 text-blue-700 rounded border border-blue-300">
                                🎸{" "}
                                {(() => {
                                  const firstChord =
                                    song.chords.match(/\b([A-G](?:#|b)?)/);
                                  return firstChord ? firstChord[1] : "C";
                                })()}
                              </span>
                            </div>
                          )}
                        </div>
                        <div className="text-sm text-gray-600 mb-3">
                          {song.artist || song.band || "Unknown Artist"}
                        </div>
                        <div className="flex gap-2">
                          <button
                            onClick={() => openSong(song)}
                            className="flex-1 px-3 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors text-sm font-semibold"
                          >
                            View
                          </button>
                          <button
                            onClick={() => addSongToUserProfile(song)}
                            disabled={isAnimating}
                            className="flex-1 px-3 py-2 bg-purple-600 text-white rounded hover:bg-purple-700 transition-colors text-sm font-semibold disabled:opacity-50 disabled:cursor-not-allowed"
                          >
                            + Add
                          </button>
                        </div>
                      </div>
                    );
                  })
                ) : (
                  <div className="col-span-full text-center text-gray-500 py-8">
                    {allSongsSearchQ
                      ? "No songs found"
                      : "Type to search songs"}
                  </div>
                )}
              </div>
            </div>

            {/* Saved Songs Section */}
            <div className="mb-8">
              <div className="max-w-7xl mx-auto">
                <div className="flex justify-between items-center mb-4">
                  <h3 className="text-2xl font-bold text-gray-800">
                    📚 Your Saved Songs ({profileSongs.length})
                  </h3>
                </div>

                <input
                  value={savedSongsSearchQ}
                  onChange={(e) => setSavedSongsSearchQ(e.target.value)}
                  placeholder="Search your saved songs..."
                  className="w-full p-4 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500 mb-4"
                />
              </div>

              <div className="max-w-7xl mx-auto">
                {filteredSavedSongs.length > 0 ? (
                  <div className="profile-songs-grid md:grid md:grid-cols-3 md:gap-6">
                    {filteredSavedSongs.map((song) => (
                      <div
                        key={song.id}
                        onClick={() => openSong(song)}
                        className="bg-white border-2 border-gray-200 rounded-lg md:rounded-xl p-3 md:p-6 hover:border-purple-400 hover:shadow-xl transition-all cursor-pointer flex flex-col"
                        style={{
                          backgroundImage:
                            "linear-gradient(to bottom, #ffffff 0%, #f9fafb 100%)",
                        }}
                      >
                        <div className="flex justify-between items-start mb-2 md:mb-4">
                          <div className="flex-1">
                            <h4 className="text-base md:text-xl font-bold text-gray-800 mb-1">
                              {song.title}
                            </h4>
                            <div className="flex items-center gap-1 md:gap-2 mb-1 flex-wrap">
                              {song.singer && (
                                <p className="text-xs md:text-sm text-purple-600 font-semibold">
                                  🎤 {song.singer}
                                </p>
                              )}
                              {song.chords && (
                                <span className="inline-block px-1 md:px-2 py-0.5 md:py-1 text-xs font-bold bg-blue-100 text-blue-700 rounded border border-blue-300">
                                  🎸 Key:{" "}
                                  {(() => {
                                    const firstChord =
                                      song.chords.match(/\b([A-G](?:#|b)?)/);
                                    return firstChord ? firstChord[1] : "C";
                                  })()}
                                </span>
                              )}
                            </div>
                            <p className="text-xs md:text-sm text-gray-600">
                              {song.artist || song.band}
                            </p>
                          </div>
                          <button
                            onClick={(e) => {
                              e.stopPropagation();
                              removeSongFromUserProfile(song.id);
                            }}
                            className="text-red-600 hover:text-red-800 font-bold text-lg md:text-xl ml-2"
                            title="Remove from profile"
                          >
                            ×
                          </button>
                        </div>
                        <div className="text-sm text-gray-700 max-h-32 overflow-hidden flex-1">
                          {song.lyrics ? (
                            <pre className="whitespace-pre-wrap font-mono text-xs leading-relaxed">
                              {song.lyrics.slice(0, 200)}
                              {song.lyrics.length > 200 && "..."}
                            </pre>
                          ) : (
                            <p className="italic text-gray-400">
                              No lyrics available
                            </p>
                          )}
                        </div>
                        <div className="mt-2 md:mt-4 pt-2 md:pt-4 border-t border-gray-200">
                          <div className="text-center text-xs text-purple-600 font-semibold">
                            🎵 Tap to view →
                          </div>
                        </div>
                      </div>
                    ))}
                  </div>
                ) : (
                  <div className="text-center py-16 bg-gray-50 rounded-xl border-2 border-dashed border-gray-300">
                    <div className="text-6xl mb-4">🎵</div>
                    <p className="text-xl text-gray-600 mb-2">
                      No saved songs yet
                    </p>
                    <p className="text-gray-500">
                      Search and add songs from the section above
                    </p>
                  </div>
                )}
              </div>
            </div>

            {modal && (
              <LyricModal
                modal={modal}
                setModal={setModal}
                onSave={async () => {
                  if (!modal.id) {
                    const created = await createSong({
                      title: modal.title,
                      artist: modal.artist,
                      band: modal.band,
                      lyrics: modal.lyrics,
                      chords: modal.chords,
                      singer: modal.singer,
                    });
                    // Attach new id to local modal so subsequent edits use PUT
                    setModal({ ...modal, id: created.id, isBlankSheet: false });
                    // Trigger sync event for other components/devices
                    window.dispatchEvent(
                      new CustomEvent("songsChanged", {
                        detail: { id: created.id },
                      })
                    );
                  } else {
                    await saveSong(modal.id, {
                      title: modal.title,
                      artist: modal.artist,
                      band: modal.band,
                      lyrics: modal.lyrics,
                      chords: modal.chords,
                      singer: modal.singer,
                    });
                    // Trigger sync event for other components/devices
                    window.dispatchEvent(
                      new CustomEvent("songsChanged", {
                        detail: { id: modal.id },
                      })
                    );
                  }
                  await loadProfileSongs(viewingProfileId);
                }}
                profileKey="C"
                profileId={viewingProfileId}
              />
            )}
          </>
        ) : null}
      </div>
    );
  }

  // Profile Management View
  return (
    <div
      className="container-fluid px-3 px-md-4 py-4 mx-auto"
      style={{ maxWidth: "1400px" }}
    >
      <h2 className="text-2xl md:text-3xl font-bold mb-4 md:mb-6 text-gray-800">
        Profile Management
      </h2>

      {/* Profile Search */}
      <div className="mb-4 md:mb-6">
        <input
          value={profileSearchQ}
          onChange={(e) => setProfileSearchQ(e.target.value)}
          placeholder="🔍 Search profiles..."
          className="w-100 p-3 md:p-4 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500"
          style={{ fontSize: "14px" }}
        />
      </div>

      <div className="row g-3 g-md-4">
        {/* LEFT: All Profiles List */}
        <div className="col-12 col-lg-6">
          <div className="border-2 border-gray-300 p-3 p-md-4 rounded-xl bg-white">
            <h3 className="text-xl md:text-2xl font-bold mb-3 md:mb-4 text-gray-800">
              All Profiles ({filteredProfiles.length})
            </h3>
            {/* On mobile: no max-height scroll, on desktop: max-height with scroll */}
            <div
              className="space-y-3 md:max-h-[600px] md:overflow-y-auto"
              style={{
                scrollbarWidth: "thin",
                msOverflowStyle: "auto",
              }}
            >
              <style>{`
                .profile-list-container::-webkit-scrollbar {
                  display: none;
                }
              `}</style>
              {filteredProfiles.map((p) => (
                <div
                  key={p.id}
                  className="border-2 border-gray-200 p-3 rounded-lg hover:border-purple-400 hover:shadow-md transition-all mb-3"
                >
                  <div className="d-flex flex-column flex-md-row justify-content-between align-items-start gap-3">
                    <div className="flex-grow-1" style={{ minWidth: 0 }}>
                      <div
                        className="font-bold text-base md:text-lg text-gray-800"
                        style={{ wordBreak: "break-word" }}
                      >
                        {p.name}
                      </div>
                      <div
                        className="text-xs md:text-sm text-gray-600"
                        style={{ wordBreak: "break-word" }}
                      >
                        {p.email || "No email"}
                      </div>
                    </div>
                    <div
                      className="d-flex gap-2 align-items-center flex-shrink-0"
                      style={{ marginLeft: "auto" }}
                    >
                      <button
                        onClick={() => editProfile(p)}
                        className="btn btn-sm d-flex align-items-center justify-content-center"
                        style={{
                          fontSize: "11px",
                          padding: "8px 12px",
                          backgroundColor: "#3b82f6",
                          borderColor: "#3b82f6",
                          color: "white",
                          minWidth: "60px",
                          whiteSpace: "nowrap",
                        }}
                        title="Edit Profile"
                      >
                        ✏️ Edit
                      </button>
                      <button
                        onClick={() => viewProfile(p.id)}
                        className="btn btn-sm d-flex align-items-center justify-content-center"
                        style={{
                          fontSize: "11px",
                          padding: "8px 12px",
                          backgroundColor: "#9333ea",
                          borderColor: "#9333ea",
                          color: "white",
                          minWidth: "60px",
                          whiteSpace: "nowrap",
                        }}
                        title="View Profile"
                      >
                        👁️ View
                      </button>
                      <button
                        onClick={() => setDeleteConfirmProfile(p)}
                        className="btn btn-sm d-flex align-items-center justify-content-center"
                        style={{
                          fontSize: "11px",
                          padding: "8px 12px",
                          backgroundColor: "#ef4444",
                          borderColor: "#ef4444",
                          color: "white",
                          minWidth: "60px",
                          whiteSpace: "nowrap",
                        }}
                        title="Delete Profile"
                      >
                        🗑️ Del
                      </button>
                    </div>
                  </div>
                </div>
              ))}
            </div>
          </div>
        </div>

        {/* RIGHT: Create/Edit Profile Form */}
        <div className="col-12 col-lg-6">
          <div
            className="border-2 border-gray-300 p-3 p-md-4 rounded-xl"
            style={{
              background: "linear-gradient(to bottom right, #faf5ff, #eff6ff)",
            }}
          >
            <h3 className="text-xl md:text-2xl font-bold mb-4 md:mb-6 text-gray-800">
              {editing ? "Edit Profile" : "Create New Profile"}
            </h3>
            <div className="space-y-3">
              <div className="row g-2">
                <div className="col-12 col-sm-6">
                  <input
                    value={firstName}
                    onChange={(e) => setFirstName(e.target.value)}
                    placeholder="First Name"
                    className="w-100 p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500"
                    style={{ fontSize: "14px" }}
                  />
                </div>
                <div className="col-12 col-sm-6">
                  <input
                    value={lastName}
                    onChange={(e) => setLastName(e.target.value)}
                    placeholder="Last Name"
                    className="w-100 p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500"
                    style={{ fontSize: "14px" }}
                  />
                </div>
              </div>
              <input
                type="email"
                value={email}
                onChange={(e) => setEmail(e.target.value)}
                placeholder="Email Address"
                className="w-100 p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500"
                style={{ fontSize: "14px" }}
              />
              <input
                type="tel"
                value={contactNumber}
                onChange={(e) => setContactNumber(e.target.value)}
                placeholder="Contact Number"
                className="w-100 p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500"
                style={{ fontSize: "14px" }}
              />
              <textarea
                value={notes}
                onChange={(e) => setNotes(e.target.value)}
                placeholder="Notes..."
                className="w-100 p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500 resize-y"
                rows={4}
                style={{ fontSize: "14px" }}
              />
              <div className="d-flex flex-column flex-sm-row gap-2">
                {editing && (
                  <button
                    onClick={clearForm}
                    className="btn btn-secondary w-100"
                    style={{ fontSize: "14px", padding: "10px" }}
                  >
                    Cancel
                  </button>
                )}
                <button
                  onClick={saveProfile}
                  disabled={!firstName || !lastName}
                  className="btn w-100"
                  style={{
                    fontSize: "14px",
                    padding: "10px",
                    backgroundColor: "#9333ea",
                    borderColor: "#9333ea",
                    color: "white",
                  }}
                >
                  {editing ? "Update Profile" : "Create Profile"}
                </button>
              </div>
            </div>
          </div>
        </div>
      </div>

      {/* Delete Profile Confirmation Modal */}
      {deleteConfirmProfile && (
        <div
          onClick={() => setDeleteConfirmProfile(null)}
          style={{
            position: "fixed",
            inset: 0,
            background: "rgba(0,0,0,0.7)",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            zIndex: 10000,
          }}
        >
          <div
            onClick={(e) => e.stopPropagation()}
            className="bg-white p-8 rounded-xl shadow-2xl max-w-md"
          >
            <h3 className="text-xl font-bold text-gray-800 mb-4">
              Confirm Delete Profile
            </h3>
            <p className="text-gray-600 mb-6">
              Are you sure you want to delete the profile{" "}
              <span className="font-semibold">{deleteConfirmProfile.name}</span>
              ? This will also remove all songs associated with this profile.
              This action cannot be undone.
            </p>
            <div className="flex gap-3 justify-end">
              <button
                onClick={() => setDeleteConfirmProfile(null)}
                className="px-6 py-2 bg-gray-500 text-white rounded-lg hover:bg-gray-600 transition-colors font-semibold"
              >
                No, Cancel
              </button>
              <button
                onClick={() => handleDeleteProfile(deleteConfirmProfile.id)}
                className="px-6 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors font-semibold"
              >
                Yes, Delete
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

/**
 * Database Component
 *
 * Features mobile-native navigation:
 * - Browser back button support (Android/iPhone)
 * - Swipe-right gesture to go back (iOS-style)
 * - Step-by-step navigation through modals
 * - History stack management for proper back navigation
 */
function Database() {
  const navigate = useNavigate();
  const isMobile = useIsMobile();

  const [q, setQ] = useState("");
  const [songs, setSongs] = useState([]);
  const [viewingSong, setViewingSong] = useState(null);
  const [deleteConfirm, setDeleteConfirm] = useState(null);

  // Touch gesture state for swipe-to-go-back
  const [touchStart, setTouchStart] = useState(null);
  const [touchEnd, setTouchEnd] = useState(null);

  // Minimum swipe distance (in px) to trigger back
  const minSwipeDistance = 50;

  // Lock body scroll when modal is open - simplified to avoid layout shifts
  // Only lock on desktop
  useEffect(() => {
    const shouldLock = !isMobile && (viewingSong || deleteConfirm);
    if (shouldLock) {
      const originalOverflow = document.body.style.overflow;
      const scrollY = window.scrollY;

      document.body.style.overflow = "hidden";
      document.body.style.touchAction = "none";

      return () => {
        document.body.style.overflow = originalOverflow;
        document.body.style.touchAction = "";
        window.scrollTo(0, scrollY);
      };
    }
  }, [viewingSong, deleteConfirm, isMobile]);

  async function load() {
    const res = await searchLocalSongs(q);
    // Filter out songs with empty, blank, or "Untitled" titles
    const filteredSongs = (res || []).filter(
      (song) =>
        song.title &&
        song.title.trim() !== "" &&
        song.title.trim().toLowerCase() !== "untitled"
    );
    setSongs(filteredSongs);
  }

  async function handleDelete(songId) {
    await deleteSong(songId);
    setDeleteConfirm(null);
    setViewingSong(null);
    await load();
    // Trigger sync event for other devices
    window.dispatchEvent(
      new CustomEvent("songsChanged", { detail: { id: songId, deleted: true } })
    );
  }

  async function openSong(song) {
    const full = await getSong(song.id);

    if (isMobile) {
      // On mobile: navigate to full-page view
      navigate("/view-database-song", { state: { song: full } });
    } else {
      // On desktop: open modal
      setViewingSong(full);
      // Push state to browser history for back button support
      window.history.pushState(
        {
          modal: "viewingSong",
          songId: song.id,
          returnTo: "database",
        },
        "",
        window.location.pathname + window.location.search
      );
    }
  }

  const closeSong = () => {
    setViewingSong(null);
    setDeleteConfirm(null);
  };

  const closeDeleteConfirm = () => {
    setDeleteConfirm(null);
  };

  // Handle browser back button
  useEffect(() => {
    const handlePopState = (event) => {
      event.preventDefault();

      // Close any open modals when back button is pressed
      // Check in reverse order (most recent first)
      if (deleteConfirm) {
        setDeleteConfirm(null);
      } else if (viewingSong) {
        setViewingSong(null);
      } else {
        // If no modals are open, allow normal navigation
        return;
      }

      // Re-push state to prevent actual navigation away from page
      window.history.pushState(
        {
          page: "database",
          preventNav: true,
        },
        "",
        window.location.pathname + window.location.search
      );
    };

    window.addEventListener("popstate", handlePopState);

    return () => {
      window.removeEventListener("popstate", handlePopState);
    };
  }, [viewingSong, deleteConfirm]);

  // Handle Escape key to close modals
  useEffect(() => {
    const handleEscape = (event) => {
      if (event.key === "Escape") {
        // Close modals in reverse order (most recent first)
        if (deleteConfirm) {
          setDeleteConfirm(null);
        } else if (viewingSong) {
          setViewingSong(null);
        }
      }
    };

    // Only add listener if a modal is open
    if (viewingSong || deleteConfirm) {
      window.addEventListener("keydown", handleEscape);
      return () => {
        window.removeEventListener("keydown", handleEscape);
      };
    }
  }, [viewingSong, deleteConfirm]);

  // Handle swipe gestures for iOS and Android
  const onTouchStart = (e) => {
    setTouchEnd(null);
    setTouchStart(e.targetTouches[0].clientX);
  };

  const onTouchMove = (e) => {
    setTouchEnd(e.targetTouches[0].clientX);
  };

  const onTouchEnd = () => {
    if (!touchStart || !touchEnd) return;

    const distance = touchStart - touchEnd;
    const isLeftSwipe = distance > minSwipeDistance;
    const isRightSwipe = distance < -minSwipeDistance;

    // Right swipe (swipe from left edge) = go back
    if (isRightSwipe && touchStart < 50) {
      // Only trigger if swipe starts from left edge
      if (deleteConfirm) {
        setDeleteConfirm(null);
      } else if (viewingSong) {
        setViewingSong(null);
      }
    }
  };

  // Initialize history state on mount
  useEffect(() => {
    // Push initial state to create a history entry for this page
    window.history.replaceState(
      {
        page: "database",
        isInitial: true,
      },
      "",
      window.location.pathname + window.location.search
    );
  }, []);

  // Auto-search when query changes + listen for cross-device updates
  useEffect(() => {
    const timer = setTimeout(() => {
      load();
    }, 300); // 300ms debounce for search

    // Auto-refresh when songs change on other devices
    const handleSongsChange = () => {
      load();
    };
    window.addEventListener("songsChanged", handleSongsChange);

    return () => {
      clearTimeout(timer);
      window.removeEventListener("songsChanged", handleSongsChange);
    };
  }, [q]);

  return (
    <div className="p-3 md:p-8 max-w-7xl mx-auto">
      <h2 className="text-2xl md:text-3xl font-bold mb-3 md:mb-4">
        Song Database
      </h2>
      <div className="mb-4 md:mb-6 flex gap-2 md:gap-3">
        <input
          value={q}
          onChange={(e) => setQ(e.target.value)}
          placeholder="Search songs..."
          className="flex-1 p-2 md:p-3 text-sm md:text-base border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500"
        />
        <button
          onClick={load}
          className="px-4 md:px-6 py-2 md:py-3 text-sm md:text-base bg-blue-600 text-white rounded-lg cursor-pointer hover:bg-blue-700 transition-colors font-semibold"
        >
          Search
        </button>
      </div>

      {/* Song Grid - Database: MOBILE=compact 2col, DESKTOP=large 3col like Profile */}
      <div className="grid gap-2 md:gap-6 grid-cols-2 md:grid-cols-3">
        {songs.map((song) => (
          <div
            key={song.id}
            onClick={() => openSong(song)}
            className="bg-white border-2 border-gray-200 p-3 md:p-6 rounded-lg md:rounded-xl hover:border-purple-400 hover:shadow-xl transition-all cursor-pointer flex flex-col"
            style={{
              backgroundImage:
                "linear-gradient(to bottom, #ffffff 0%, #f9fafb 100%)",
            }}
          >
            <div className="flex-1">
              <h4 className="font-bold text-gray-800 mb-1 md:mb-2 text-sm md:text-xl leading-tight md:leading-normal">
                {song.title}
              </h4>
              <div className="flex items-center flex-wrap gap-1 md:gap-2 mb-1 md:mb-3">
                {song.singer && (
                  <p className="text-purple-600 font-semibold text-xs md:text-sm">
                    🎤 {song.singer}
                  </p>
                )}
                {song.chords && (
                  <span className="inline-block px-1 md:px-2 py-0.5 md:py-1 text-xs font-bold bg-blue-100 text-blue-700 rounded border border-blue-300">
                    🎸{" "}
                    {(() => {
                      const firstChord = song.chords.match(/\b([A-G](?:#|b)?)/);
                      return firstChord ? firstChord[1] : "C";
                    })()}
                  </span>
                )}
              </div>
              {song.lyrics && (
                <div
                  className="text-gray-600 leading-relaxed overflow-hidden text-xs"
                  style={{
                    display: "-webkit-box",
                    WebkitLineClamp: 3,
                    WebkitBoxOrient: "vertical",
                    maxHeight: "60px",
                  }}
                >
                  {song.lyrics}
                </div>
              )}
            </div>
            <div className="mt-2 md:mt-4 pt-2 md:pt-4 border-t border-gray-200">
              <div className="text-center text-purple-600 font-semibold text-xs md:text-sm">
                Tap to View →
              </div>
            </div>
          </div>
        ))}
      </div>

      {songs.length === 0 && (
        <div
          style={{
            textAlign: "center",
            padding: 60,
            color: "#9ca3af",
            fontSize: 16,
          }}
        >
          {q ? "No songs found" : "Search to find songs"}
        </div>
      )}

      {/* Song View Modal */}
      {viewingSong && (
        <div
          onClick={closeSong}
          onTouchStart={onTouchStart}
          onTouchMove={onTouchMove}
          onTouchEnd={onTouchEnd}
          style={{
            position: "fixed",
            inset: 0,
            background: "rgba(0,0,0,0.75)",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            zIndex: 10000,
            backdropFilter: "blur(4px)",
          }}
        >
          <div
            onClick={(e) => e.stopPropagation()}
            style={{
              background: "white",
              borderRadius: 20,
              padding: 32,
              width: "95%",
              maxWidth: 1000,
              maxHeight: "90vh",
              overflow: "auto",
              boxShadow: "0 20px 60px rgba(0,0,0,0.3)",
              position: "relative",
            }}
          >
            {/* Swipe indicator for mobile */}
            <div
              style={{
                position: "absolute",
                top: 8,
                left: "50%",
                transform: "translateX(-50%)",
                width: 40,
                height: 4,
                background: "#d1d5db",
                borderRadius: 2,
                display: "block",
              }}
              className="md:hidden"
            />

            <div
              style={{
                display: "flex",
                justifyContent: "space-between",
                alignItems: "center",
                marginBottom: 24,
                paddingBottom: 16,
                borderBottom: "2px solid #e5e7eb",
              }}
            >
              <div>
                <h2
                  style={{
                    fontSize: 32,
                    fontWeight: "bold",
                    marginBottom: 8,
                    color: "#1f2937",
                  }}
                >
                  {viewingSong.title}
                </h2>
                {viewingSong.singer && (
                  <div
                    style={{
                      fontSize: 16,
                      color: "#7c3aed",
                      fontStyle: "italic",
                      marginBottom: 4,
                    }}
                  >
                    🎤 {viewingSong.singer}
                  </div>
                )}
                <div style={{ fontSize: 14, color: "#6b7280" }}>
                  {viewingSong.artist} — {viewingSong.band}
                </div>
              </div>
              <div style={{ display: "flex", gap: 12 }}>
                <button
                  onClick={closeSong}
                  style={{
                    padding: "10px 20px",
                    background: "#6b7280",
                    color: "white",
                    border: "none",
                    borderRadius: 8,
                    cursor: "pointer",
                    fontWeight: "600",
                    fontSize: 14,
                  }}
                >
                  ← Back
                </button>
              </div>
            </div>

            {/* Embedded LyricModal Component */}
            <LyricModal
              modal={viewingSong}
              setModal={setViewingSong}
              onSave={async () => {
                await saveSong(viewingSong.id, {
                  title: viewingSong.title,
                  artist: viewingSong.artist,
                  band: viewingSong.band,
                  lyrics: viewingSong.lyrics,
                  chords: viewingSong.chords,
                  singer: viewingSong.singer,
                });
                await load();
                // Trigger sync events for both songs and plans
                window.dispatchEvent(
                  new CustomEvent("songsChanged", {
                    detail: { id: viewingSong.id },
                  })
                );
                window.dispatchEvent(new Event("plansChanged"));
              }}
              profileId={null}
            />
            {/* Database-specific action footer */}
            <div className="mt-8 pt-6 border-t border-gray-200 grid grid-cols-2 gap-3">
              <button
                onClick={() => {
                  setDeleteConfirm(viewingSong.id);
                  window.history.pushState(
                    {
                      modal: "deleteConfirm",
                      songId: viewingSong.id,
                      returnTo: "viewingSong",
                    },
                    "",
                    window.location.pathname + window.location.search
                  );
                }}
                className="px-6 py-3 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors font-semibold flex items-center justify-center gap-2"
              >
                🗑️ Delete Song
              </button>
              <button
                onClick={closeSong}
                className="px-6 py-3 bg-gray-600 text-white rounded-lg hover:bg-gray-700 transition-colors font-semibold flex items-center justify-center gap-2"
              >
                ← Back
              </button>
            </div>
          </div>
        </div>
      )}

      {deleteConfirm && (
        <div
          onClick={closeDeleteConfirm}
          onTouchStart={onTouchStart}
          onTouchMove={onTouchMove}
          onTouchEnd={onTouchEnd}
          style={{
            position: "fixed",
            inset: 0,
            background: "rgba(0,0,0,0.6)",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            zIndex: 10000,
          }}
        >
          <div
            onClick={(e) => e.stopPropagation()}
            style={{
              background: "white",
              borderRadius: 16,
              padding: 32,
              maxWidth: 400,
              boxShadow: "0 8px 32px rgba(0,0,0,0.3)",
            }}
          >
            <h3 style={{ fontSize: 20, fontWeight: "bold", marginBottom: 16 }}>
              ⚠️ Delete Song?
            </h3>
            <p style={{ marginBottom: 24, color: "#666" }}>
              Are you sure you want to permanently delete this song? This action
              cannot be undone.
            </p>
            <div style={{ display: "flex", gap: 12 }}>
              <button
                onClick={() => handleDelete(deleteConfirm)}
                style={{
                  flex: 1,
                  padding: "12px 24px",
                  background: "#dc2626",
                  color: "white",
                  border: "none",
                  borderRadius: 8,
                  cursor: "pointer",
                  fontWeight: "bold",
                }}
              >
                Yes, Delete
              </button>
              <button
                onClick={() => setDeleteConfirm(null)}
                style={{
                  flex: 1,
                  padding: "12px 24px",
                  background: "#6b7280",
                  color: "white",
                  border: "none",
                  borderRadius: 8,
                  cursor: "pointer",
                  fontWeight: "bold",
                }}
              >
                Cancel
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

function LyricModal({
  modal,
  setModal,
  onSave,
  profileKey = "C",
  profileId = null,
  viewingPlan = null,
  onNavigateNext = null,
  onNavigatePrev = null,
}) {
  const [showChords, setShowChords] = useState(true);
  const [editMode, setEditMode] = useState(false);
  const [lyrics, setLyrics] = useState(modal?.lyrics || "");
  const [chords, setChords] = useState(modal?.chords || "");
  const [transpose, setTranspose] = useState(profileKey || "C");
  const [memo, setMemo] = useState("");
  const [title, setTitle] = useState(modal?.title || "");
  const [singer, setSinger] = useState(modal?.singer || "");
  const [originalKey, setOriginalKey] = useState("C");
  const [currentKey, setCurrentKey] = useState("C");

  // Scroll tracking for navigation buttons
  const [showNavButtons, setShowNavButtons] = useState(true);
  const [showBottomNav, setShowBottomNav] = useState(false);
  const [lastScrollY, setLastScrollY] = useState(0);
  const scrollContainerRef = useRef(null);
  const [capo, setCapo] = useState(0);
  const [showSingerSelector, setShowSingerSelector] = useState(false);

  // Update state when modal prop changes
  useEffect(() => {
    async function loadSongData() {
      setLyrics(modal?.lyrics || "");
      setTitle(modal?.title || "");
      setSinger(modal?.singer || "");

      // Auto-enable edit mode for blank sheets
      if (modal?.isBlankSheet || (!modal?.lyrics && !modal?.chords)) {
        setEditMode(true);
      }

      // Detect original key from existing chords
      if (modal?.chords) {
        const key = detectKeyFromChords(modal.chords);
        setOriginalKey(key);
        setCurrentKey(key);
        setTranspose(key);
        setChords(modal.chords);

        // Load user-specific key if profileId exists and transpose to it
        if (profileId && modal?.id) {
          const savedKey = await getProfileSongKey(profileId, modal.id);
          if (savedKey && savedKey !== key) {
            // Transpose from original key to saved key
            const transposedChords = transposeChordText(
              modal.chords,
              key,
              savedKey
            );
            setChords(transposedChords);
            setCurrentKey(savedKey);
            setTranspose(savedKey);
          }
        }
      } else {
        setChords("");
      }
    }

    loadSongData();
  }, [modal, profileId]);

  // Lock body scroll when modal is open (prevent background scrolling) - simplified to avoid layout shifts
  useEffect(() => {
    if (modal) {
      // Save original overflow style and scroll position
      const originalOverflow = document.body.style.overflow;
      const scrollY = window.scrollY;

      // Lock body scroll
      document.body.style.overflow = "hidden";
      document.body.style.touchAction = "none";

      // Cleanup: restore original styles
      return () => {
        document.body.style.overflow = originalOverflow;
        document.body.style.touchAction = "";
        window.scrollTo(0, scrollY);
      };
    }
  }, [modal]);

  // Handle scroll to show/hide navigation buttons on mobile
  useEffect(() => {
    const handleScroll = (e) => {
      const currentScrollY = e.target.scrollTop;
      const scrollHeight = e.target.scrollHeight;
      const clientHeight = e.target.clientHeight;
      const isAtBottom = scrollHeight - currentScrollY - clientHeight < 50;

      // Top navigation: show at top, hide when scrolling down
      if (currentScrollY < 50) {
        // Near top - show top nav, hide bottom nav
        setShowNavButtons(true);
        setShowBottomNav(false);
      } else if (isAtBottom) {
        // At or near bottom - always show bottom nav
        setShowNavButtons(false);
        setShowBottomNav(true);
      } else if (currentScrollY < lastScrollY) {
        // Scrolling up - show top nav, hide bottom nav
        setShowNavButtons(true);
        setShowBottomNav(false);
      } else if (currentScrollY > lastScrollY && currentScrollY > 100) {
        // Scrolling down - hide top nav, show bottom nav
        setShowNavButtons(false);
        setShowBottomNav(true);
      }

      setLastScrollY(currentScrollY);
    };

    const scrollContainer = scrollContainerRef.current;
    if (scrollContainer) {
      scrollContainer.addEventListener("scroll", handleScroll, {
        passive: true,
      });
      return () => {
        scrollContainer.removeEventListener("scroll", handleScroll);
      };
    }
  }, [lastScrollY]);

  // Chromatic scale with sharps (standard)
  const NOTES = [
    "C",
    "C#",
    "D",
    "D#",
    "E",
    "F",
    "F#",
    "G",
    "G#",
    "A",
    "A#",
    "B",
  ];

  // Flat to sharp conversions
  const FLATS = {
    Db: "C#",
    Eb: "D#",
    Gb: "F#",
    Ab: "G#",
    Bb: "A#",
    Cb: "B",
    Fb: "E",
  };

  // Comprehensive chord quality suffixes supported
  // Based on music theory: major, minor, diminished, augmented, sus, add, extensions
  const CHORD_QUALITIES = [
    // Basic triads
    "",
    "maj",
    "min",
    "m",
    "M",
    // Seventh chords
    "7",
    "maj7",
    "M7",
    "min7",
    "m7",
    "dim7",
    "aug7",
    "mMaj7",
    "mM7",
    // Extended chords
    "9",
    "maj9",
    "M9",
    "min9",
    "m9",
    "add9",
    "11",
    "maj11",
    "min11",
    "m11",
    "13",
    "maj13",
    "min13",
    "m13",
    // Suspended chords
    "sus",
    "sus2",
    "sus4",
    "7sus",
    "7sus4",
    // Altered chords
    "dim",
    "aug",
    "+",
    "º",
    "ø", // ø = half-diminished
    // Add chords
    "add2",
    "add4",
    "add11",
    // Sixth chords
    "6",
    "min6",
    "m6",
    "6/9",
    // Sharp/flat extensions
    "7b5",
    "7#5",
    "7b9",
    "7#9",
    "9#11",
    "13b9",
  ];

  // Detect key from chord progression
  function detectKeyFromChords(chordText) {
    if (!chordText) return "C";
    // Extract first chord as likely key
    const firstChord = chordText.match(/\b([A-G](?:#|b)?)/);
    return firstChord ? normalizeNote(firstChord[1]) : "C";
  }

  // Common chord progressions by key
  const CHORD_PROGRESSIONS = {
    C: ["C", "F", "G", "Am", "Dm", "Em"],
    G: ["G", "C", "D", "Em", "Am", "Bm"],
    D: ["D", "G", "A", "Bm", "Em", "F#m"],
    A: ["A", "D", "E", "F#m", "Bm", "C#m"],
    E: ["E", "A", "B", "C#m", "F#m", "G#m"],
    F: ["F", "Bb", "C", "Dm", "Gm", "Am"],
    Bb: ["Bb", "Eb", "F", "Gm", "Cm", "Dm"],
    Eb: ["Eb", "Ab", "Bb", "Cm", "Fm", "Gm"],
  };

  function normalizeNote(n) {
    return FLATS[n] || n;
  }

  function shiftNote(n, semitones) {
    const base = normalizeNote(n);
    const idx = NOTES.indexOf(base);
    if (idx < 0) return n;
    const ni = (idx + semitones + NOTES.length) % NOTES.length;
    return NOTES[ni];
  }

  // Detect if a line is a section header (Verse, Chorus, Bridge, etc.)
  function isSectionHeader(line) {
    const trimmed = line.trim();
    // Match common section patterns with optional numbering/markers
    const sectionPattern =
      /^(Verse|Chorus|Bridge|Pre-?Chorus|Intro|Outro|Tag|Interlude|Refrain|Hook|Coda|Ending)(\s*\d+)?\s*:?\s*$/i;
    return sectionPattern.test(trimmed);
  }

  function detectSemitoneShift(fromKey, toKey) {
    const from = normalizeNote(fromKey);
    const to = normalizeNote(toKey);
    const fromIdx = NOTES.indexOf(from);
    const toIdx = NOTES.indexOf(to);
    if (fromIdx < 0 || toIdx < 0) return 0;
    return (toIdx - fromIdx + 12) % 12;
  }

  function transposeChordText(text, fromKey, toKey) {
    const semis = detectSemitoneShift(fromKey, toKey);

    // First, clean up any malformed chords with multiple # or b symbols
    let cleanedText = text.replace(
      /([A-G])(#+|b+)/g,
      (match, root, accidentals) => {
        // Keep only the first # or b
        return root + accidentals[0];
      }
    );

    // Enhanced regex to handle:
    // 1. Basic chords: C, D, E, etc.
    // 2. Accidentals: C#, Db, etc.
    // 3. Qualities: maj, min, m, dim, aug, sus, etc.
    // 4. Extensions: 7, 9, 11, 13
    // 5. Alterations: b5, #9, etc.
    // 6. Slash chords: C/G, Dm7/A, etc.
    // Comprehensive pattern: Root + Accidental + Quality/Extensions + (optional /BassNote)
    const chordPattern =
      /\b([A-G])([#b]?)([^\s\/]*?)(?:\/([A-G][#b]?))?(?=\s|$|\b)/g;

    // Split by lines to handle chord lines properly
    return cleanedText
      .split("\n")
      .map((line) => {
        // Skip section headers entirely - return as-is
        if (isSectionHeader(line)) {
          return line;
        }

        // Check if this looks like a chord line
        const noteCount = (line.match(/\b[A-G][#b]?/g) || []).length;
        const isChordLine = noteCount >= 1;

        return line.replace(
          chordPattern,
          (match, root, accidental, quality, bassNote, offset) => {
            // Always transpose if it has accidental, quality, or bass note
            if (accidental || quality || bassNote) {
              const originalChord = root + (accidental || "");
              const newRoot = shiftNote(originalChord, semis);

              // Transpose bass note if present (slash chord)
              let newBass = "";
              if (bassNote) {
                newBass = "/" + shiftNote(bassNote, semis);
              }

              return newRoot + quality + newBass;
            }

            // For single letters, check context
            const beforeChar = offset > 0 ? line[offset - 1] : "";
            const afterChar =
              offset + match.length < line.length
                ? line[offset + match.length]
                : "";

            if (
              isChordLine ||
              beforeChar === "" ||
              /\s/.test(beforeChar) ||
              /\s|$/.test(afterChar)
            ) {
              const newRoot = shiftNote(root, semis);
              return newRoot + quality;
            }

            return match;
          }
        );
      })
      .join("\n");
  }

  // Auto-generate chord placement above lyrics
  function autoPlaceChords(lyricText, key) {
    if (!lyricText) return "";
    const progression = CHORD_PROGRESSIONS[key] || CHORD_PROGRESSIONS["C"];
    const lines = lyricText.split("\n");
    let chordLines = [];
    let chordIndex = 0;

    lines.forEach((line, idx) => {
      // Skip empty lines
      if (!line.trim()) {
        chordLines.push("");
        return;
      }

      // Skip section headers - no chords assigned
      if (isSectionHeader(line)) {
        chordLines.push("");
        return;
      }

      // Place chords at strategic positions (beginning and middle of lines)
      const words = line.trim().split(/\s+/);
      if (words.length > 0) {
        const chord1 = progression[chordIndex % progression.length];
        chordIndex++;

        let chordLine = chord1;

        // Add second chord if line is long enough
        if (words.length > 4) {
          const chord2 = progression[chordIndex % progression.length];
          chordIndex++;
          const midPoint = Math.floor(line.length / 2);
          chordLine = chord1.padEnd(midPoint) + chord2;
        }

        chordLines.push(chordLine);
      } else {
        chordLines.push("");
      }
    });

    return chordLines.join("\n");
  }

  function close() {
    setModal(null);
  }

  function toggleChords() {
    setShowChords((v) => !v);
  }

  async function doTranspose() {
    const targetKey = transpose;

    // If no chords exist, auto-generate them
    if (!modal?.chords || modal.chords.trim() === "") {
      const generated = autoPlaceChords(lyrics, targetKey);
      setChords(generated);
      setOriginalKey(targetKey);
      setCurrentKey(targetKey);
    } else {
      // Always transpose from the original stored chords for accuracy
      const semitones = detectSemitoneShift(originalKey, targetKey);

      const newChords = transposeChordText(
        modal.chords,
        originalKey,
        targetKey
      );

      // Force state update
      setChords(newChords);
      setCurrentKey(targetKey);
    }

    // Save user-specific key preference
    if (profileId && modal?.id) {
      await saveProfileSongKey(profileId, modal.id, targetKey);
    }
  }

  async function save() {
    // Validate title is not empty
    if (!title || title.trim() === "") {
      alert("Please enter a song title before saving.");
      return;
    }

    if (modal) {
      modal.title = title.trim();
      modal.lyrics = lyrics;
      modal.chords = chords;
      modal.singer = singer;
    }
    await onSave();
    close();
  }

  return (
    <div
      onClick={close}
      style={{
        position: "fixed",
        inset: 0,
        background: "rgba(0,0,0,0.75)",
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        zIndex: 10000,
        backdropFilter: "blur(4px)",
      }}
    >
      <div
        onClick={(e) => e.stopPropagation()}
        style={{
          background: "linear-gradient(to bottom, #ffffff 0%, #f8f9fa 100%)",
          borderRadius: 20,
          width: "98%",
          maxWidth: 1000,
          maxHeight: "95vh",
          boxShadow: "0 20px 60px rgba(0,0,0,0.3)",
          border: "1px solid rgba(255,255,255,0.8)",
          position: "relative",
          overflow: "hidden",
        }}
      >
        <div
          ref={scrollContainerRef}
          className="custom-scrollbar"
          style={{
            padding: "16px",
            maxHeight: "95vh",
            overflow: "auto",
          }}
        >
          {/* Title Header - Compact Editable */}
          {modal?.isBlankSheet || editMode ? (
            <div>
              <input
                type="text"
                value={title}
                onChange={(e) => setTitle(e.target.value)}
                placeholder="Enter song title..."
                className="w-full font-bold text-xl mb-3 p-3 border border-gray-300 rounded-lg focus:border-purple-500 focus:outline-none focus:ring-1 focus:ring-purple-500"
                style={{
                  fontFamily: "'Roboto', 'Arial', sans-serif",
                  color: "#1a1a1a",
                }}
              />
              <div className="relative">
                <input
                  type="text"
                  value={singer}
                  onClick={() =>
                    modal?.isBlankSheet && setShowSingerSelector(true)
                  }
                  onChange={(e) => setSinger(e.target.value)}
                  placeholder="Who's singing this song?"
                  className="w-full font-semibold text-base mb-3 p-2.5 border border-gray-300 rounded-lg focus:border-purple-500 focus:outline-none focus:ring-1 focus:ring-purple-500 cursor-pointer"
                  style={{
                    fontFamily: "'Roboto', 'Arial', sans-serif",
                    color: "#555",
                  }}
                />
                {/* Singer Selection Popup */}
                {showSingerSelector && (
                  <div
                    className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-[9999]"
                    onClick={() => setShowSingerSelector(false)}
                  >
                    <div
                      className="bg-white rounded-2xl shadow-2xl p-8 max-w-md w-full mx-4"
                      onClick={(e) => e.stopPropagation()}
                    >
                      <h2 className="text-2xl font-bold mb-2 text-gray-800">
                        Select Singer
                      </h2>
                      <p className="text-gray-600 mb-6 text-sm">
                        Choose who will be singing this song
                      </p>
                      <div className="space-y-3">
                        {["Camilah", "Merve", "David", "Paul", "Kristen"].map(
                          (name) => (
                            <button
                              key={name}
                              onClick={() => {
                                setSinger(name);
                                setShowSingerSelector(false);
                              }}
                              className="w-full px-6 py-4 bg-gradient-to-r from-purple-500 to-purple-600 text-white rounded-xl font-semibold text-lg hover:from-purple-600 hover:to-purple-700 transition-all transform hover:scale-105 shadow-md hover:shadow-lg"
                            >
                              🎤 {name}
                            </button>
                          )
                        )}
                      </div>
                      <button
                        onClick={() => setShowSingerSelector(false)}
                        className="w-full mt-4 px-6 py-3 bg-gray-200 text-gray-700 rounded-xl font-semibold hover:bg-gray-300 transition-colors"
                      >
                        Cancel
                      </button>
                    </div>
                  </div>
                )}
              </div>
            </div>
          ) : (
            <div>
              {/* Title Section - Compact */}
              <div className="mb-3">
                <div
                  className="font-bold text-2xl"
                  style={{
                    fontFamily: "'Roboto', 'Arial', sans-serif",
                    color: "#1a1a1a",
                    letterSpacing: "-0.3px",
                  }}
                >
                  {modal?.title || "Song"}
                </div>
                {singer && (
                  <div
                    className="text-base mt-1"
                    style={{
                      fontFamily: "'Roboto', 'Arial', sans-serif",
                      color: "#666",
                      fontStyle: "italic",
                    }}
                  >
                    🎤 {singer}
                  </div>
                )}
              </div>

              {/* Navigation Buttons - Compact Sticky */}
              {viewingPlan &&
                viewingPlan.songs &&
                viewingPlan.songs.length > 1 &&
                onNavigateNext &&
                onNavigatePrev && (
                  <div
                    className="sticky top-2 z-50 mb-3 transition-all duration-300"
                    style={{
                      opacity: showNavButtons ? 1 : 0,
                      transform: showNavButtons
                        ? "translateY(0)"
                        : "translateY(-20px)",
                      pointerEvents: showNavButtons ? "auto" : "none",
                    }}
                  >
                    <div className="flex items-center justify-center gap-2">
                      <button
                        onClick={onNavigatePrev}
                        disabled={
                          viewingPlan.songs.findIndex(
                            (s) => s.id === modal.id
                          ) === 0
                        }
                        className="flex items-center justify-center w-8 h-8 bg-blue-500 text-white rounded-lg font-semibold shadow-md hover:bg-blue-600 disabled:bg-gray-300 disabled:cursor-not-allowed transition-all"
                        title="Previous"
                      >
                        <svg
                          className="w-4 h-4"
                          fill="none"
                          stroke="currentColor"
                          viewBox="0 0 24 24"
                        >
                          <path
                            strokeLinecap="round"
                            strokeLinejoin="round"
                            strokeWidth={2}
                            d="M15 19l-7-7 7-7"
                          />
                        </svg>
                      </button>

                      <div className="px-3 py-1 bg-white rounded-lg text-xs font-medium text-gray-600 shadow-sm border border-gray-200">
                        {viewingPlan.songs.findIndex((s) => s.id === modal.id) +
                          1}{" "}
                        / {viewingPlan.songs.length}
                      </div>

                      <button
                        onClick={onNavigateNext}
                        disabled={
                          viewingPlan.songs.findIndex(
                            (s) => s.id === modal.id
                          ) ===
                          viewingPlan.songs.length - 1
                        }
                        className="flex items-center justify-center w-8 h-8 bg-blue-500 text-white rounded-lg font-semibold shadow-md hover:bg-blue-600 disabled:bg-gray-300 disabled:cursor-not-allowed transition-all"
                        title="Next"
                      >
                        <svg
                          className="w-4 h-4"
                          fill="none"
                          stroke="currentColor"
                          viewBox="0 0 24 24"
                        >
                          <path
                            strokeLinecap="round"
                            strokeLinejoin="round"
                            strokeWidth={2}
                            d="M9 5l7 7-7 7"
                          />
                        </svg>
                      </button>
                    </div>
                  </div>
                )}
              <div className="mb-4 pb-4 border-b-2 border-gray-200"></div>
            </div>
          )}
          {/* Controls Bar */}
          <div className="mb-6 bg-gray-50 p-4 rounded-xl space-y-4">
            {/* Key Info Section */}
            {!modal?.isBlankSheet && (
              <div className="flex flex-wrap gap-3 items-center">
                <div className="flex items-center gap-2">
                  <span className="text-sm font-semibold text-gray-700">
                    Sounding Key:
                  </span>
                  <span className="px-3 py-1 bg-purple-100 text-purple-800 rounded-lg font-bold">
                    {currentKey}
                  </span>
                </div>

                {capo > 0 && (
                  <div className="flex items-center gap-2">
                    <span className="text-sm font-semibold text-gray-700">
                      Play As:
                    </span>
                    <span className="px-3 py-1 bg-green-100 text-green-800 rounded-lg font-bold">
                      {(() => {
                        const soundingIdx = NOTES.indexOf(
                          normalizeNote(currentKey)
                        );
                        const playedIdx = (soundingIdx - capo + 12) % 12;
                        return NOTES[playedIdx];
                      })()}
                    </span>
                    <span className="text-xs text-gray-600">(Capo {capo})</span>
                  </div>
                )}
              </div>
            )}

            {/* Chord Progression Display */}
            {!modal?.isBlankSheet &&
              (modal?.chord_progression ||
                (chords && chords.includes(" - "))) && (
                <div className="bg-white p-3 rounded-lg border border-purple-200">
                  <div className="text-sm font-semibold text-gray-700 mb-1">
                    Chord Progression:
                  </div>
                  <div className="text-purple-600 font-bold text-base">
                    {modal?.chord_progression || chords}
                  </div>
                </div>
              )}

            {/* Dropdowns Section */}
            {!modal?.isBlankSheet && (
              <div className="grid grid-cols-2 gap-3">
                <select
                  value={transpose}
                  onChange={(e) => {
                    const targetKey = e.target.value;
                    setTranspose(targetKey);
                    // Auto-transpose when key changes
                    setTimeout(() => {
                      if (chords && chords.trim() !== "") {
                        const newChords = transposeChordText(
                          chords,
                          currentKey,
                          targetKey
                        );
                        setChords(newChords);
                        setCurrentKey(targetKey);

                        // Save preference
                        if (profileId && modal?.id) {
                          saveProfileSongKey(profileId, modal.id, targetKey);
                        }
                      }
                    }, 0);
                  }}
                  className="px-4 py-2 border-2 border-gray-300 rounded-lg focus:border-purple-500 focus:outline-none font-semibold"
                >
                  {[
                    "C",
                    "C#",
                    "D",
                    "D#",
                    "E",
                    "F",
                    "F#",
                    "G",
                    "G#",
                    "A",
                    "A#",
                    "B",
                  ].map((k) => (
                    <option key={k} value={k}>
                      {k}
                    </option>
                  ))}
                </select>

                <select
                  value={capo}
                  onChange={(e) => setCapo(parseInt(e.target.value))}
                  className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:border-green-500 focus:outline-none focus:ring-1 focus:ring-green-500 bg-gray-50"
                >
                  <option value={0}>No Capo</option>
                  {[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15].map(
                    (c) => (
                      <option key={c} value={c}>
                        Capo {c}
                      </option>
                    )
                  )}
                </select>
              </div>
            )}

            {/* Action Buttons - Responsive Grid */}
            <div className="grid grid-cols-2 sm:grid-cols-3 gap-2">
              {!modal?.isBlankSheet && (
                <>
                  <button
                    onClick={doTranspose}
                    className="px-3 py-2 text-sm bg-purple-600 text-white rounded-md hover:bg-purple-700 transition-colors font-medium shadow-sm"
                  >
                    {modal?.chords ? "🎵 Key" : "✨ Gen"}
                  </button>

                  <button
                    onClick={toggleChords}
                    className={`px-3 py-2 text-sm rounded-md transition-colors font-medium shadow-sm ${
                      showChords
                        ? "bg-green-600 text-white hover:bg-green-700"
                        : "bg-gray-200 text-gray-700 hover:bg-gray-300"
                    }`}
                  >
                    {showChords ? "🎸 On" : "Off"}
                  </button>

                  {/* Hide Edit button when viewing from worship list */}
                  {!viewingPlan && (
                    <button
                      onClick={() => setEditMode(!editMode)}
                      className={`px-3 py-2 text-sm rounded-md transition-colors font-medium shadow-sm ${
                        editMode
                          ? "bg-orange-600 text-white hover:bg-orange-700"
                          : "bg-gray-200 text-gray-700 hover:bg-gray-300"
                      }`}
                    >
                      {editMode ? "✏️" : "Edit"}
                    </button>
                  )}
                </>
              )}

              {/* Hide Save button when viewing from worship list */}
              {!viewingPlan && (
                <button
                  onClick={save}
                  className="px-3 py-2 text-sm bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors font-medium shadow-sm"
                >
                  💾 Save
                </button>
              )}

              {/* Hide Delete button when viewing from worship list */}
              {!viewingPlan && modal?.id && (
                <button
                  onClick={async () => {
                    // If viewing from a profile, only remove association (not delete from database)
                    if (profileId) {
                      if (
                        !window.confirm("Remove this song from your profile?")
                      )
                        return;
                      try {
                        await removeSongFromProfile(profileId, modal.id);
                        // Dispatch both events to sync across all devices and components
                        window.dispatchEvent(
                          new CustomEvent("profileSongsChanged", {
                            detail: { profile_id: profileId },
                          })
                        );
                        window.dispatchEvent(new CustomEvent("songsChanged"));
                      } catch (e) {
                        alert(
                          "Failed to remove song from profile. Please try again."
                        );
                      } finally {
                        close();
                      }
                    } else {
                      // No profile context, delete from database
                      if (
                        !window.confirm("Delete this song sheet permanently?")
                      )
                        return;
                      try {
                        await deleteSong(modal.id);
                        // Dispatch songsChanged to sync across all devices
                        window.dispatchEvent(
                          new CustomEvent("songsChanged", {
                            detail: { id: modal.id },
                          })
                        );
                        window.dispatchEvent(new CustomEvent("plansChanged"));
                      } catch (e) {
                        alert("Failed to delete song. Please try again.");
                      } finally {
                        close();
                      }
                    }
                  }}
                  className="px-3 py-2 text-sm bg-red-600 text-white rounded-md hover:bg-red-700 transition-colors font-medium shadow-sm"
                >
                  🗑️
                </button>
              )}

              <button
                onClick={close}
                className="px-3 py-2 text-sm bg-gray-600 text-white rounded-md hover:bg-gray-700 transition-colors font-medium shadow-sm"
              >
                ✕ Close
              </button>
            </div>
          </div>
          {/* Memo Section - Compact */}
          {editMode && (
            <div className="mb-4">
              <label className="block text-xs font-semibold text-gray-600 mb-2">
                📝 Notes
              </label>
              <textarea
                value={memo}
                onChange={(e) => setMemo(e.target.value)}
                placeholder="Add performance notes, special instructions, or reminders..."
                className="w-full p-3 border border-gray-300 rounded-lg focus:border-purple-500 focus:outline-none focus:ring-1 focus:ring-purple-500 resize-y text-sm"
                style={{
                  minHeight: "80px",
                  fontFamily: "'Inter', 'Segoe UI', sans-serif",
                }}
              />
            </div>
          )}

          {/* Capo Display on Song Sheet - Compact */}
          {!editMode && capo > 0 && (
            <div className="mb-3 p-3 bg-green-50 border-l-4 border-green-500 rounded-lg">
              <div className="flex items-center gap-2">
                <span className="text-xl">🎸</span>
                <div>
                  <div className="font-bold text-green-800 text-sm">
                    Capo Fret {capo}
                  </div>
                  <div className="text-xs text-green-700">
                    Play:{" "}
                    {(() => {
                      const soundingIdx = NOTES.indexOf(
                        normalizeNote(currentKey)
                      );
                      const playedIdx = (soundingIdx - capo + 12) % 12;
                      return NOTES[playedIdx];
                    })()}{" "}
                    • Sounds: {currentKey}
                  </div>
                </div>
              </div>
            </div>
          )}

          {/* Lyrics Display Area - Compact Mobile-Friendly */}
          <div>
            <div className="font-bold text-base mb-2 text-gray-700">
              {editMode ? "✏️ Edit Lyrics" : "🎵 Song Sheet"}
            </div>
            {editMode ? (
              <textarea
                value={lyrics}
                onChange={(e) => setLyrics(e.target.value)}
                placeholder="Paste or type your lyrics here..."
                className="w-full p-4 border border-gray-300 rounded-lg focus:border-purple-500 focus:outline-none focus:ring-1 focus:ring-purple-500 resize-y"
                style={{
                  minHeight: "400px",
                  fontFamily: "'Roboto', 'Arial', sans-serif",
                  fontSize: "16px",
                  lineHeight: "1.6",
                }}
              />
            ) : (
              <div
                key={currentKey + "-" + chords.length}
                className="w-full p-4 border border-gray-200 rounded-lg bg-white"
                style={{
                  minHeight: "400px",
                  fontFamily: "'Roboto', 'Arial', sans-serif",
                  fontSize: "16px",
                  lineHeight: "1.8",
                  whiteSpace: "pre-wrap",
                  overflow: "auto",
                  background: "#ffffff",
                }}
              >
                {showChords && chords
                  ? // Display chords above lyrics with capo adjustment
                    lyrics.split("\n").map((line, idx) => {
                      let chordLine = chords.split("\n")[idx] || "";

                      // Apply capo adjustment to displayed chords
                      if (capo > 0 && chordLine) {
                        chordLine = chordLine.replace(
                          /\b([A-G])([#b]?)((?:maj|min|m|sus|aug|dim|add|\d)*)/g,
                          (match, root, accidental, suffix) => {
                            if (!accidental && !suffix && match.length === 1) {
                              return match;
                            }
                            const originalChord = root + (accidental || "");
                            const shiftedNote = shiftNote(originalChord, -capo);
                            return shiftedNote + suffix;
                          }
                        );
                      }

                      return (
                        <div key={idx} className="mb-3">
                          {chordLine && (
                            <div
                              className="font-bold mb-0.5"
                              style={{
                                color: "#7c3aed",
                                fontSize: "15px",
                                fontFamily: "'Roboto', 'Arial', sans-serif",
                                letterSpacing: "0.3px",
                              }}
                            >
                              {chordLine}
                            </div>
                          )}
                          <div
                            style={{
                              color: "#1a1a1a",
                              fontSize: "16px",
                              fontFamily: "'Roboto', 'Arial', sans-serif",
                              fontWeight: line.trim() === "" ? "normal" : "500",
                            }}
                          >
                            {line || "\u00A0"}
                          </div>
                        </div>
                      );
                    })
                  : lyrics}
              </div>
            )}

            {/* Fixed Bottom Navigation - Shows when scrolling */}
            {viewingPlan &&
              viewingPlan.songs &&
              viewingPlan.songs.length > 1 &&
              onNavigateNext &&
              onNavigatePrev && (
                <div
                  className="fixed left-0 right-0 bottom-0 z-50 transition-all duration-300 px-4 pb-3"
                  style={{
                    transform: showBottomNav
                      ? "translateY(0)"
                      : "translateY(100px)",
                    opacity: showBottomNav ? 1 : 0,
                    pointerEvents: showBottomNav ? "auto" : "none",
                  }}
                >
                  <div
                    className="flex items-center justify-center gap-3 bg-white rounded-xl px-4 py-2.5 shadow-2xl border-2 border-blue-200 mx-auto"
                    style={{
                      maxWidth: "360px",
                      backdropFilter: "blur(10px)",
                      backgroundColor: "rgba(255, 255, 255, 0.98)",
                    }}
                  >
                    <button
                      onClick={onNavigatePrev}
                      disabled={
                        viewingPlan.songs.findIndex(
                          (s) => s.id === modal.id
                        ) === 0
                      }
                      className="flex items-center justify-center w-10 h-10 bg-blue-500 text-white rounded-lg font-bold shadow-lg hover:bg-blue-600 disabled:bg-gray-300 disabled:cursor-not-allowed transition-all active:scale-95"
                      title="Previous"
                      style={{
                        flexShrink: 0,
                      }}
                    >
                      <svg
                        className="w-5 h-5"
                        fill="none"
                        stroke="currentColor"
                        viewBox="0 0 24 24"
                      >
                        <path
                          strokeLinecap="round"
                          strokeLinejoin="round"
                          strokeWidth={3}
                          d="M15 19l-7-7 7-7"
                        />
                      </svg>
                    </button>

                    <div className="flex-1 text-center px-3">
                      <div
                        className="text-xl font-bold text-gray-800"
                        style={{ lineHeight: "1" }}
                      >
                        {viewingPlan.songs.findIndex((s) => s.id === modal.id) +
                          1}
                        <span className="text-gray-500 mx-1">/</span>
                        {viewingPlan.songs.length}
                      </div>
                    </div>

                    <button
                      onClick={onNavigateNext}
                      disabled={
                        viewingPlan.songs.findIndex(
                          (s) => s.id === modal.id
                        ) ===
                        viewingPlan.songs.length - 1
                      }
                      className="flex items-center justify-center w-10 h-10 bg-blue-500 text-white rounded-lg font-bold shadow-lg hover:bg-blue-600 disabled:bg-gray-300 disabled:cursor-not-allowed transition-all active:scale-95"
                      title="Next"
                      style={{
                        flexShrink: 0,
                      }}
                    >
                      <svg
                        className="w-5 h-5"
                        fill="none"
                        stroke="currentColor"
                        viewBox="0 0 24 24"
                      >
                        <path
                          strokeLinecap="round"
                          strokeLinejoin="round"
                          strokeWidth={3}
                          d="M9 5l7 7-7 7"
                        />
                      </svg>
                    </button>
                  </div>
                </div>
              )}
          </div>
        </div>
      </div>
    </div>
  );
}

// Worksheet Preview Box Component with Hover Preview
function WorksheetPreviewBox({ plan, onClick }) {
  const [showPreview, setShowPreview] = useState(false);
  const [previewData, setPreviewData] = useState(null);
  const [hoverTimeout, setHoverTimeout] = useState(null);

  async function handleMouseEnter() {
    // Delay preview to avoid flickering
    const timeout = setTimeout(async () => {
      try {
        const songs = await fetchPlanSongs(plan.id);
        setPreviewData(songs);
        setShowPreview(true);
      } catch (err) {}
    }, 300);
    setHoverTimeout(timeout);
  }

  function handleMouseLeave() {
    if (hoverTimeout) {
      clearTimeout(hoverTimeout);
      setHoverTimeout(null);
    }
    setShowPreview(false);
  }

  return (
    <div
      style={{ position: "relative" }}
      onMouseEnter={handleMouseEnter}
      onMouseLeave={handleMouseLeave}
    >
      <div
        onClick={onClick}
        style={{
          border: "2px solid #ddd",
          borderRadius: 12,
          padding: 20,
          background: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
          color: "white",
          textAlign: "center",
          cursor: "pointer",
          transition: "all 0.3s ease",
          boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
          minHeight: 140,
          display: "flex",
          flexDirection: "column",
          justifyContent: "center",
          alignItems: "center",
        }}
        onMouseEnter={(e) => {
          e.currentTarget.style.transform = "translateY(-4px)";
          e.currentTarget.style.boxShadow = "0 8px 16px rgba(0,0,0,0.2)";
        }}
        onMouseLeave={(e) => {
          e.currentTarget.style.transform = "translateY(0)";
          e.currentTarget.style.boxShadow = "0 2px 8px rgba(0,0,0,0.1)";
        }}
      >
        <div style={{ fontSize: 14, opacity: 0.9, marginBottom: 8 }}>
          Worship List
        </div>
        <div style={{ fontWeight: "bold", fontSize: 20, marginBottom: 8 }}>
          {(() => {
            const [year, month, day] = plan.date.split("-");
            return new Date(year, month - 1, day).toLocaleDateString("en-US", {
              month: "short",
              day: "numeric",
              year: "numeric",
            });
          })()}
        </div>
        <div
          style={{
            fontSize: 12,
            padding: "6px 12px",
            background: "rgba(255,255,255,0.2)",
            borderRadius: 20,
            marginTop: 4,
          }}
        >
          Click to Open
        </div>
      </div>

      {/* Hover Preview Popup */}
      {showPreview && previewData && (
        <div
          style={{
            position: "absolute",
            top: "100%",
            left: "50%",
            transform: "translateX(-50%)",
            marginTop: 8,
            background: "white",
            border: "2px solid #667eea",
            borderRadius: 12,
            padding: 16,
            boxShadow: "0 8px 24px rgba(0,0,0,0.2)",
            zIndex: 10000,
            minWidth: 250,
            maxWidth: 350,
          }}
          onMouseEnter={() => setShowPreview(true)}
          onMouseLeave={handleMouseLeave}
        >
          <div
            style={{
              fontWeight: "bold",
              fontSize: 16,
              marginBottom: 12,
              color: "#333",
              borderBottom: "2px solid #667eea",
              paddingBottom: 8,
            }}
          >
            📋 Worksheet Preview
          </div>
          {previewData.length > 0 ? (
            <div>
              <div style={{ fontSize: 12, color: "#666", marginBottom: 8 }}>
                {previewData.length} song{previewData.length !== 1 ? "s" : ""}{" "}
                planned
              </div>
              <div style={{ maxHeight: 200, overflow: "auto" }}>
                {previewData.slice(0, 5).map((song, idx) => (
                  <div
                    key={idx}
                    style={{
                      padding: "6px 8px",
                      marginBottom: 4,
                      background: "#f5f5f5",
                      borderRadius: 6,
                      fontSize: 13,
                      color: "#333",
                    }}
                  >
                    {idx + 1}. Song #{song.song_id}
                  </div>
                ))}
                {previewData.length > 5 && (
                  <div style={{ fontSize: 12, color: "#999", marginTop: 8 }}>
                    +{previewData.length - 5} more...
                  </div>
                )}
              </div>
            </div>
          ) : (
            <div style={{ fontSize: 13, color: "#999", fontStyle: "italic" }}>
              No songs added yet
            </div>
          )}
        </div>
      )}
    </div>
  );
}

function Planning() {
  const [plans, setPlans] = useState([]);
  const [newDate, setNewDate] = useState("");
  const [selected, setSelected] = useState(null);
  const [planSongs, setPlanSongs] = useState([]);
  const [localQ, setLocalQ] = useState("");
  const [localResults, setLocalResults] = useState([]);
  const [memo, setMemo] = useState("");
  const [lyricModal, setLyricModal] = useState(null);
  const [selectedProfileId, setSelectedProfileId] = useState(null);
  const [showCreateDay, setShowCreateDay] = useState(false);
  const [editingPlan, setEditingPlan] = useState(null);
  const [planNotes, setPlanNotes] = useState("");
  const [planSongSearch, setPlanSongSearch] = useState("");
  const [planSearchResults, setPlanSearchResults] = useState([]);
  const [chosenSongs, setChosenSongs] = useState([]);
  const [addedSongId, setAddedSongId] = useState(null);
  const [viewingPlan, setViewingPlan] = useState(null);
  const [viewingPlanSong, setViewingPlanSong] = useState(null);
  const [deleteConfirmPlan, setDeleteConfirmPlan] = useState(null);

  // Lock body scroll when any modal is open - simplified to avoid layout shifts
  useEffect(() => {
    if (
      lyricModal ||
      viewingPlan ||
      viewingPlanSong ||
      showCreateDay ||
      editingPlan ||
      deleteConfirmPlan
    ) {
      const originalOverflow = document.body.style.overflow;
      const scrollY = window.scrollY;

      document.body.style.overflow = "hidden";
      document.body.style.touchAction = "none";

      return () => {
        document.body.style.overflow = originalOverflow;
        document.body.style.touchAction = "";
        window.scrollTo(0, scrollY);
      };
    }
  }, [
    lyricModal,
    viewingPlan,
    viewingPlanSong,
    showCreateDay,
    editingPlan,
    deleteConfirmPlan,
  ]);

  async function load() {
    const res = await fetchPlans();
    if (res) {
      // Load full song data for each plan
      const plansWithSongs = await Promise.all(
        res.map(async (plan) => {
          const songs = await fetchPlanSongs(plan.id);
          const fullSongs = await Promise.all(
            (songs || []).map(async (ps) => {
              const song = await getSong(ps.song_id);
              return { ...song, order: ps.order_index };
            })
          );
          return { ...plan, songs: fullSongs };
        })
      );
      setPlans(plansWithSongs);
    } else {
      setPlans([]);
    }
  }
  useEffect(() => {
    load();
    // Load selected profile
    const savedId = localStorage.getItem("selected_profile_id");
    if (savedId) {
      // Keep as string to support UUID profile IDs
      setSelectedProfileId(savedId);
    }
    // Listen for profile changes
    const handleProfileChange = () => {
      const updatedId = localStorage.getItem("selected_profile_id");
      if (updatedId) {
        // Keep as string to support UUID profile IDs
        setSelectedProfileId(updatedId);
      }
    };
    window.addEventListener("profileChanged", handleProfileChange);

    // Listen for plan changes from Home component
    const handlePlansChange = () => {};
    // Listen for song changes - refresh plan songs if viewing a plan
    const handleSongsChange = () => {
      if (selected) {
        load(); // Reload to get updated song data
      }
      if (planSongSearch.trim()) {
        searchPlanSongs(); // Refresh search results
      }
    };
    window.addEventListener("plansChanged", handlePlansChange);
    window.addEventListener("songsChanged", handleSongsChange);

    return () => {
      window.removeEventListener("profileChanged", handleProfileChange);
      window.removeEventListener("plansChanged", handlePlansChange);
      window.removeEventListener("songsChanged", handleSongsChange);
    };
  }, [selected, planSongSearch]);
  async function create() {
    // Keep as string to support UUID profile IDs
    const profileId =
      selectedProfileId || localStorage.getItem("selected_profile_id") || 1;
    const p = await createPlan({ date: newDate, profile_id: profileId });
    await load();
  }
  async function openPlan(p) {
    setSelected(p.id);
    const rows = await fetchPlanSongs(p.id);
    // Load full song details
    const fullSongs = await Promise.all(
      (rows || []).map(async (ps) => {
        const song = await getSong(ps.song_id);
        return song;
      })
    );
    setPlanSongs(fullSongs);
  }
  async function searchLocal() {
    if (!localQ.trim()) {
      setLocalResults([]);
      return;
    }
    const res = await searchLocalSongs(localQ);
    setLocalResults(res || []);
  }
  async function pinSong(song) {
    if (!selected) return;
    await addSongToPlan(selected, {
      song_id: song.id,
      order_index: planSongs.length || 0,
    });
    const rows = await fetchPlanSongs(selected);
    setPlanSongs(rows || []);
  }
  async function moveUp(idx) {
    if (idx <= 0) return;
    const swapped = [...planSongs];
    const tmp = swapped[idx - 1];
    swapped[idx - 1] = swapped[idx];
    swapped[idx] = tmp;
    setPlanSongs(swapped);
  }
  async function moveDown(idx) {
    if (idx >= planSongs.length - 1) return;
    const swapped = [...planSongs];
    const tmp = swapped[idx + 1];
    swapped[idx + 1] = swapped[idx];
    swapped[idx] = tmp;
    setPlanSongs(swapped);
  }

  // Navigate to next song in worship plan
  async function navigateToNextSong() {
    if (!viewingPlan || !viewingPlan.songs || !viewingPlanSong) return;

    const currentIndex = viewingPlan.songs.findIndex(
      (s) => s.id === viewingPlanSong.id
    );
    if (currentIndex < viewingPlan.songs.length - 1) {
      const nextSong = viewingPlan.songs[currentIndex + 1];
      const fullSong = await getSong(nextSong.id);
      setViewingPlanSong(fullSong);
    }
  }

  // Navigate to previous song in worship plan
  async function navigateToPrevSong() {
    if (!viewingPlan || !viewingPlan.songs || !viewingPlanSong) return;

    const currentIndex = viewingPlan.songs.findIndex(
      (s) => s.id === viewingPlanSong.id
    );
    if (currentIndex > 0) {
      const prevSong = viewingPlan.songs[currentIndex - 1];
      const fullSong = await getSong(prevSong.id);
      setViewingPlanSong(fullSong);
    }
  }

  async function openLyric(r) {
    const full = await getSong(r.id);
    setLyricModal(full);
  }

  async function createNewDay() {
    if (!newDate) return;

    const planData = {
      date: newDate,
      profile_id: selectedProfileId,
      notes: planNotes,
    };

    let planId;
    if (editingPlan) {
      // When editing, pass songs to updatePlan so it clears old ones
      await updatePlan(editingPlan.id, {
        ...planData,
        songs: chosenSongs,
      });
      planId = editingPlan.id;
    } else {
      const created = await createPlan(planData);
      planId = created.id;

      // Add songs to the new plan
      for (let i = 0; i < chosenSongs.length; i++) {
        await addSongToPlan(planId, {
          song_id: chosenSongs[i].id,
          order_index: i,
        });
      }
    }

    await load();
    // Notify Home component to reload plans
    window.dispatchEvent(new Event("plansChanged"));
    closePlanModal();
  }

  function closePlanModal() {
    setShowCreateDay(false);
    setEditingPlan(null);
    setNewDate("");
    setPlanNotes("");
    setChosenSongs([]);
    setPlanSongSearch("");
    setPlanSearchResults([]);
  }

  function openEditPlan(plan) {
    setEditingPlan(plan);
    setNewDate(plan.date);
    setPlanNotes(plan.notes || "");
    setChosenSongs(plan.songs || []);
    setShowCreateDay(true);
    setViewingPlan(null);
  }

  async function handleDeletePlan(planId) {
    if (!deleteConfirmPlan) return;

    try {
      console.log("=== START DELETE PROCESS (Planning) ===");
      console.log("handleDeletePlan - Deleting plan:", planId);

      // Delete the plan
      const result = await deletePlan(planId);
      console.log("Delete result:", result);

      // Close modals immediately
      setDeleteConfirmPlan(null);
      setViewingPlan(null);

      // Clear the current plans state to force fresh fetch
      setPlans([]);

      // Small delay to ensure backend has committed the change
      await new Promise((resolve) => setTimeout(resolve, 100));

      // Force complete refresh of plans
      console.log("Reloading plans...");
      await load();

      // Notify Home component to reload
      window.dispatchEvent(new Event("plansChanged"));

      console.log("=== DELETE PROCESS COMPLETE (Planning) ===");
    } catch (error) {
      console.error("Error deleting plan:", error);
      alert("Failed to delete worship list. Please try again.");
    }
  }

  async function searchPlanSongs() {
    if (!planSongSearch.trim()) {
      setPlanSearchResults([]);
      return;
    }
    const results = await searchLocalSongs(planSongSearch);
    const validResults = (results || []).filter(
      (song) =>
        song.title &&
        song.title.trim() !== "" &&
        song.title.trim().toLowerCase() !== "untitled"
    );
    setPlanSearchResults(validResults);
  }

  function addSongToChosen(song) {
    if (!chosenSongs.find((s) => s.id === song.id)) {
      setChosenSongs([...chosenSongs, song]);

      // Check if search matches artist/band/singer (keep search) or song title (clear search)
      const searchLower = planSongSearch.toLowerCase().trim();
      const artistMatch = (song.artist || "")
        .toLowerCase()
        .includes(searchLower);
      const bandMatch = (song.band || "").toLowerCase().includes(searchLower);
      const singerMatch = (song.singer || "")
        .toLowerCase()
        .includes(searchLower);
      const titleMatch = (song.title || "").toLowerCase().includes(searchLower);

      // If searching by artist/band/singer, keep the search
      // If searching by title only, clear it
      const isArtistSearch =
        (artistMatch || bandMatch || singerMatch) && !titleMatch;

      if (!isArtistSearch) {
        // Clear search only if it was a title search
        setPlanSongSearch("");
      }
    }
  }

  function removeSongFromChosen(songId) {
    setChosenSongs(chosenSongs.filter((s) => s.id !== songId));
  }

  function moveSongUp(index) {
    if (index === 0) return;
    const newSongs = [...chosenSongs];
    [newSongs[index - 1], newSongs[index]] = [
      newSongs[index],
      newSongs[index - 1],
    ];
    setChosenSongs(newSongs);
  }

  function moveSongDown(index) {
    if (index === chosenSongs.length - 1) return;
    const newSongs = [...chosenSongs];
    [newSongs[index], newSongs[index + 1]] = [
      newSongs[index + 1],
      newSongs[index],
    ];
    setChosenSongs(newSongs);
  }

  function handleDragStart(e, index) {
    e.dataTransfer.effectAllowed = "move";
    e.dataTransfer.setData("text/plain", index.toString());
  }

  function handleDragOver(e) {
    e.preventDefault();
    e.dataTransfer.dropEffect = "move";
  }

  function handleDrop(e, dropIndex) {
    e.preventDefault();
    const dragIndex = parseInt(e.dataTransfer.getData("text/plain"));
    if (dragIndex === dropIndex) return;

    const newSongs = [...chosenSongs];
    const [removed] = newSongs.splice(dragIndex, 1);
    newSongs.splice(dropIndex, 0, removed);
    setChosenSongs(newSongs);
  }

  return (
    <div className="p-6 max-w-7xl mx-auto" style={{ paddingTop: "2rem" }}>
      <h2 className="text-3xl font-bold mb-6 text-gray-800">Worship List</h2>

      {/* Create Worship List Button */}
      <div className="mb-8">
        <button
          onClick={() => {
            setShowCreateDay(true);
            setEditingPlan(null);
            setNewDate(new Date().toISOString().split("T")[0]);
            setPlanNotes("");
            setChosenSongs([]);
          }}
          className="px-6 py-3 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition-colors font-semibold shadow-md"
        >
          ➕ Create Worship List
        </button>
      </div>

      {/* Latest Worship List - Featured Card */}
      {plans.length > 0 &&
        (() => {
          const sorted = [...plans].sort((a, b) => (a.date > b.date ? -1 : 1));
          const latestPlan = sorted[0];
          return (
            <div
              onClick={() => setViewingPlan(latestPlan)}
              style={{
                background: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
                borderRadius: 16,
                padding: 32,
                marginBottom: 24,
                cursor: "pointer",
                boxShadow: "0 4px 16px rgba(0,0,0,0.15)",
                transition: "all 0.3s ease",
                minHeight: 180,
                display: "flex",
                flexDirection: "column",
                justifyContent: "center",
                alignItems: "center",
              }}
              onMouseEnter={(e) => {
                e.currentTarget.style.transform = "translateY(-4px)";
                e.currentTarget.style.boxShadow = "0 8px 24px rgba(0,0,0,0.25)";
              }}
              onMouseLeave={(e) => {
                e.currentTarget.style.transform = "translateY(0)";
                e.currentTarget.style.boxShadow = "0 4px 16px rgba(0,0,0,0.15)";
              }}
            >
              <div
                style={{
                  fontSize: 16,
                  color: "rgba(255,255,255,0.9)",
                  marginBottom: 8,
                }}
              >
                📋 Most Recent Worship List
              </div>
              <div
                style={{
                  fontWeight: "bold",
                  fontSize: 32,
                  color: "white",
                  marginBottom: 12,
                }}
              >
                {(() => {
                  const [year, month, day] = latestPlan.date.split("-");
                  return new Date(year, month - 1, day).toLocaleDateString(
                    "en-US",
                    {
                      weekday: "long",
                      month: "long",
                      day: "numeric",
                      year: "numeric",
                    }
                  );
                })()}
              </div>
              <div
                style={{
                  fontSize: 14,
                  color: "rgba(255,255,255,0.85)",
                  padding: "8px 16px",
                  background: "rgba(255,255,255,0.15)",
                  borderRadius: 20,
                  maxWidth: "80%",
                  textAlign: "center",
                }}
              >
                {latestPlan.notes || "Click to view and edit this worship list"}
              </div>
            </div>
          );
        })()}

      {/* All Worship Lists Grid */}
      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 mb-8">
        {plans.map((p) => (
          <div
            key={p.id}
            onClick={() => setViewingPlan(p)}
            className="worship-card"
            style={{
              background: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
              borderRadius: 12,
              padding: "20px 24px",
              cursor: "pointer",
              minHeight: "140px",
              display: "flex",
              flexDirection: "column",
              justifyContent: "space-between",
            }}
          >
            <div>
              <div
                style={{
                  fontSize: 12,
                  color: "rgba(255,255,255,0.9)",
                  marginBottom: 8,
                  fontWeight: 600,
                  letterSpacing: "0.5px",
                }}
              >
                WORSHIP LIST
              </div>
              <div
                style={{
                  fontWeight: "bold",
                  fontSize: 20,
                  color: "white",
                  marginBottom: 8,
                }}
              >
                {(() => {
                  const [year, month, day] = p.date.split("-");
                  return new Date(year, month - 1, day).toLocaleDateString(
                    "en-US",
                    {
                      weekday: "short",
                      month: "short",
                      day: "numeric",
                      year: "numeric",
                    }
                  );
                })()}
              </div>
            </div>
            <div style={{ fontSize: 13, color: "rgba(255,255,255,0.85)" }}>
              {p.songs && p.songs.length > 0
                ? `${p.songs.length} songs`
                : "No songs added"}
              {p.notes && " • Notes available"}
            </div>
          </div>
        ))}
      </div>

      {plans.length === 0 && (
        <div className="text-center py-16 bg-gray-50 rounded-xl border-2 border-dashed border-gray-300">
          <div className="text-6xl mb-4">📅</div>
          <p className="text-xl text-gray-600 mb-2">No worship lists yet</p>
          <p className="text-gray-500">
            Create your first worship list to get started
          </p>
        </div>
      )}
      {/* Sheet View Modal - Same as Home component */}
      {viewingPlan && (
        <div
          onClick={() => setViewingPlan(null)}
          style={{
            position: "fixed",
            inset: 0,
            background: "rgba(0,0,0,0.7)",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            zIndex: 10000,
            overflow: "auto",
            padding: "20px",
          }}
        >
          <div
            onClick={(e) => e.stopPropagation()}
            style={{
              background: "white",
              padding: 40,
              borderRadius: 16,
              width: "100%",
              maxWidth: 700,
              maxHeight: "90vh",
              overflow: "auto",
              boxShadow: "0 20px 60px rgba(0,0,0,0.4)",
            }}
          >
            <div className="flex justify-between items-start mb-6">
              <div>
                <h2 className="text-3xl font-bold text-gray-800 mb-2">
                  Worship List
                </h2>
                <div className="text-xl text-purple-600 font-semibold">
                  {(() => {
                    const [year, month, day] = viewingPlan.date.split("-");
                    return new Date(year, month - 1, day).toLocaleDateString(
                      "en-US",
                      {
                        weekday: "long",
                        month: "long",
                        day: "numeric",
                        year: "numeric",
                      }
                    );
                  })()}
                </div>
              </div>
              <button
                onClick={() => setViewingPlan(null)}
                className="text-gray-500 hover:text-gray-700 text-2xl font-bold"
              >
                ×
              </button>
            </div>

            {/* Notes Section */}
            {viewingPlan.notes && (
              <div className="mb-6 p-4 bg-yellow-50 border-l-4 border-yellow-400 rounded">
                <h3 className="text-sm font-semibold text-gray-700 mb-2">
                  Notes
                </h3>
                <p className="text-gray-700 whitespace-pre-wrap">
                  {viewingPlan.notes}
                </p>
              </div>
            )}

            {/* Song Lineup */}
            <div className="mb-6">
              <h3 className="text-lg font-semibold text-gray-800 mb-4">
                Song Lineup
              </h3>
              {viewingPlan.songs && viewingPlan.songs.length > 0 ? (
                <div className="space-y-3">
                  {viewingPlan.songs.map((song, idx) => (
                    <div
                      key={idx}
                      onClick={async () => {
                        const fullSong = await getSong(song.id);
                        setViewingPlanSong(fullSong);
                      }}
                      className="flex items-center gap-3 p-3 sm:p-4 bg-gradient-to-r from-purple-50 to-blue-50 rounded-lg border border-purple-200 cursor-pointer hover:border-purple-400 hover:shadow-lg transition-all"
                    >
                      <div className="flex items-center justify-center w-8 h-8 sm:w-10 sm:h-10 bg-purple-600 text-white rounded-full font-bold text-base sm:text-lg flex-shrink-0">
                        {idx + 1}
                      </div>
                      <div className="flex-1 min-w-0">
                        <div className="font-bold text-gray-800 text-base sm:text-lg break-words">
                          {song.title}
                        </div>
                        {(song.artist || song.band) && (
                          <div className="text-xs sm:text-sm text-gray-600 truncate">
                            {song.artist || song.band}
                          </div>
                        )}
                      </div>
                      <div className="hidden sm:block text-sm text-purple-600 font-semibold flex-shrink-0">
                        Click to view →
                      </div>
                      <div className="sm:hidden text-purple-600 flex-shrink-0">
                        <svg
                          className="w-5 h-5"
                          fill="none"
                          stroke="currentColor"
                          viewBox="0 0 24 24"
                        >
                          <path
                            strokeLinecap="round"
                            strokeLinejoin="round"
                            strokeWidth={2}
                            d="M9 5l7 7-7 7"
                          />
                        </svg>
                      </div>
                    </div>
                  ))}
                </div>
              ) : (
                <div className="text-center text-gray-500 py-8 bg-gray-50 rounded-lg">
                  No songs added to this worship list
                </div>
              )}
            </div>

            {/* Action Buttons */}
            <div className="flex gap-3 justify-end pt-4 border-t border-gray-200">
              <button
                onClick={() => openEditPlan(viewingPlan)}
                className="px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-semibold flex items-center gap-2"
              >
                <span>✏️</span>
                Edit List
              </button>
              <button
                onClick={() => setDeleteConfirmPlan(viewingPlan)}
                className="px-6 py-3 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors font-semibold flex items-center gap-2"
              >
                <span>🗑️</span>
                Delete List
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Create/Edit Worship List Modal */}
      {showCreateDay && (
        <div
          onClick={closePlanModal}
          style={{
            position: "fixed",
            inset: 0,
            background: "rgba(0,0,0,0.6)",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            zIndex: 10000,
            overflow: "auto",
            padding: "20px",
          }}
        >
          <div
            onClick={(e) => e.stopPropagation()}
            style={{
              background: "white",
              padding: 32,
              borderRadius: 16,
              width: "100%",
              maxWidth: 900,
              maxHeight: "90vh",
              overflow: "auto",
              boxShadow: "0 20px 60px rgba(0,0,0,0.3)",
            }}
          >
            <h2 className="text-2xl font-bold mb-6 text-gray-800">
              {editingPlan ? "Edit Worship List" : "Create Worship List"}
            </h2>

            {/* Date Selector */}
            <div className="mb-6">
              <label className="block text-sm font-semibold text-gray-700 mb-2">
                Worship Date *
              </label>
              <input
                type="date"
                value={newDate}
                onChange={(e) => setNewDate(e.target.value)}
                onClick={(e) => e.target.showPicker && e.target.showPicker()}
                className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent cursor-pointer"
                required
              />
            </div>

            {/* Notes Section */}
            <div className="mb-6">
              <label className="block text-sm font-semibold text-gray-700 mb-2">
                Notes / Memo
              </label>
              <textarea
                value={planNotes}
                onChange={(e) => setPlanNotes(e.target.value)}
                className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent resize-y"
                rows={4}
                placeholder="Add planning notes, announcements, special instructions..."
              />
            </div>

            {/* Song Search Section */}
            <div className="mb-6">
              <label className="block text-sm font-semibold text-gray-700 mb-2">
                Search Local Songs
              </label>
              <input
                type="text"
                value={planSongSearch}
                onChange={(e) => {
                  setPlanSongSearch(e.target.value);
                  if (e.target.value.trim()) {
                    searchPlanSongs();
                  } else {
                    setPlanSearchResults([]);
                  }
                }}
                className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent mb-3"
                placeholder="Search by title, artist, or band..."
              />
              <div className="max-h-64 overflow-y-auto border border-gray-200 rounded-lg">
                {planSearchResults.length > 0
                  ? planSearchResults.map((song) => {
                      const isAdded = chosenSongs.find((s) => s.id === song.id);
                      return (
                        <div
                          key={song.id}
                          className={`p-3 border-b border-gray-100 flex justify-between items-center transition-all ${
                            isAdded ? "bg-green-50" : "hover:bg-purple-50"
                          }`}
                        >
                          <div>
                            <div className="font-semibold text-sm text-gray-800">
                              {song.title}
                            </div>
                            <div className="text-xs text-gray-600">
                              {song.artist || song.band}
                              {song.singer && (
                                <span className="ml-2 text-purple-600">
                                  🎤 {song.singer}
                                </span>
                              )}
                            </div>
                          </div>
                          {isAdded ? (
                            <div className="px-3 py-1 bg-green-500 text-white text-xs rounded flex items-center gap-1">
                              <span>✓</span> Added
                            </div>
                          ) : (
                            <button
                              onClick={() => addSongToChosen(song)}
                              className="px-3 py-1 bg-purple-600 text-white text-xs rounded hover:bg-purple-700 transition-colors"
                            >
                              Add
                            </button>
                          )}
                        </div>
                      );
                    })
                  : null}
              </div>
            </div>

            {/* Chosen Songs with Ordering */}
            <div className="mb-6">
              <label className="block text-sm font-semibold text-gray-700 mb-2">
                Chosen Songs ({chosenSongs.length}) - Drag to reorder or use
                arrows
              </label>
              <div className="border border-gray-300 rounded-lg p-4 bg-gray-50 min-h-32">
                {chosenSongs.length > 0 ? (
                  <div className="space-y-2">
                    {chosenSongs.map((song, idx) => (
                      <div
                        key={song.id}
                        draggable
                        onDragStart={(e) => handleDragStart(e, idx)}
                        onDragOver={handleDragOver}
                        onDrop={(e) => handleDrop(e, idx)}
                        className="flex items-center gap-3 bg-white p-3 rounded-lg shadow-sm cursor-move hover:shadow-md hover:border-purple-300 border border-transparent transition-all"
                        style={{ touchAction: "none" }}
                      >
                        <div className="text-gray-400 cursor-grab active:cursor-grabbing text-xl">
                          ⋮⋮
                        </div>
                        <div className="flex flex-col gap-1">
                          <button
                            onClick={() => moveSongUp(idx)}
                            disabled={idx === 0}
                            className="text-gray-600 hover:text-purple-600 disabled:text-gray-300 disabled:cursor-not-allowed text-xs"
                            title="Move up"
                          >
                            ▲
                          </button>
                          <button
                            onClick={() => moveSongDown(idx)}
                            disabled={idx === chosenSongs.length - 1}
                            className="text-gray-600 hover:text-purple-600 disabled:text-gray-300 disabled:cursor-not-allowed text-xs"
                            title="Move down"
                          >
                            ▼
                          </button>
                        </div>
                        <div className="flex-1">
                          <div className="font-semibold text-sm text-gray-800">
                            {idx + 1}. {song.title}
                          </div>
                          <div className="text-xs text-gray-600">
                            {song.artist || song.band}
                          </div>
                        </div>
                        <button
                          onClick={() => removeSongFromChosen(song.id)}
                          className="text-red-600 hover:text-red-700 font-bold text-lg"
                          title="Remove"
                        >
                          ×
                        </button>
                      </div>
                    ))}
                  </div>
                ) : (
                  <div className="text-center text-gray-500 text-sm py-8">
                    No songs chosen yet. Add songs from the search.
                  </div>
                )}
              </div>
            </div>

            {/* Action Buttons */}
            <div className="flex gap-3 justify-end">
              <button
                onClick={closePlanModal}
                className="px-6 py-3 bg-gray-500 text-white rounded-lg hover:bg-gray-600 transition-colors font-semibold"
              >
                Cancel
              </button>
              <button
                onClick={createNewDay}
                disabled={!newDate}
                className="px-6 py-3 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition-colors font-semibold disabled:bg-gray-400 disabled:cursor-not-allowed"
              >
                {editingPlan ? "Update List" : "Create List"}
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Delete Confirmation Modal */}
      {deleteConfirmPlan && (
        <div
          onClick={() => setDeleteConfirmPlan(null)}
          style={{
            position: "fixed",
            inset: 0,
            background: "rgba(0,0,0,0.7)",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            zIndex: 10000,
          }}
        >
          <div
            onClick={(e) => e.stopPropagation()}
            style={{
              background: "white",
              borderRadius: 16,
              padding: 32,
              maxWidth: 400,
              boxShadow: "0 8px 32px rgba(0,0,0,0.3)",
            }}
          >
            <h3
              id="delete-confirm-title"
              className="text-xl font-bold mb-4 text-gray-800"
            >
              ⚠️ Delete Worship List?
            </h3>
            <p id="delete-confirm-desc" className="mb-6 text-gray-600">
              Are you sure you want to delete this worship list? This action
              cannot be undone.
            </p>
            <div className="flex gap-3">
              <button
                onClick={() => handleDeletePlan(deleteConfirmPlan.id)}
                className="flex-1 px-4 py-3 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors font-semibold"
              >
                Yes, Delete
              </button>
              <button
                onClick={() => setDeleteConfirmPlan(null)}
                className="flex-1 px-4 py-3 bg-gray-500 text-white rounded-lg hover:bg-gray-600 transition-colors font-semibold"
              >
                Cancel
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Worship List Song Sheet View */}
      {viewingPlanSong && (
        <div
          onClick={() => setViewingPlanSong(null)}
          style={{
            position: "fixed",
            inset: 0,
            background: "rgba(0,0,0,0.8)",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            zIndex: 10001,
            overflow: "auto",
            padding: "12px",
          }}
        >
          <div
            onClick={(e) => e.stopPropagation()}
            className="bg-white p-4 sm:p-6 md:p-10 rounded-2xl w-full shadow-2xl"
            style={{
              maxWidth: 900,
              maxHeight: "90vh",
              overflow: "auto",
            }}
          >
            {/* Navigation Buttons */}
            {viewingPlan &&
              viewingPlan.songs &&
              viewingPlan.songs.length > 1 && (
                <div className="flex justify-center items-center gap-3 mb-6">
                  <button
                    onClick={navigateToPrevSong}
                    disabled={
                      viewingPlan.songs.findIndex(
                        (s) => s.id === viewingPlanSong.id
                      ) === 0
                    }
                    className="flex items-center gap-2 px-6 py-3 bg-gradient-to-r from-blue-500 to-blue-600 text-white rounded-lg font-semibold shadow-lg hover:from-blue-600 hover:to-blue-700 disabled:from-gray-300 disabled:to-gray-400 disabled:cursor-not-allowed transition-all transform hover:scale-105 active:scale-95"
                  >
                    <svg
                      className="w-5 h-5"
                      fill="none"
                      stroke="currentColor"
                      viewBox="0 0 24 24"
                    >
                      <path
                        strokeLinecap="round"
                        strokeLinejoin="round"
                        strokeWidth={2}
                        d="M15 19l-7-7 7-7"
                      />
                    </svg>
                    <span>Back</span>
                  </button>

                  <div className="px-4 py-2 bg-gray-100 rounded-lg text-sm font-semibold text-gray-700">
                    {viewingPlan.songs.findIndex(
                      (s) => s.id === viewingPlanSong.id
                    ) + 1}{" "}
                    / {viewingPlan.songs.length}
                  </div>

                  <button
                    onClick={navigateToNextSong}
                    disabled={
                      viewingPlan.songs.findIndex(
                        (s) => s.id === viewingPlanSong.id
                      ) ===
                      viewingPlan.songs.length - 1
                    }
                    className="flex items-center gap-2 px-6 py-3 bg-gradient-to-r from-blue-500 to-blue-600 text-white rounded-lg font-semibold shadow-lg hover:from-blue-600 hover:to-blue-700 disabled:from-gray-300 disabled:to-gray-400 disabled:cursor-not-allowed transition-all transform hover:scale-105 active:scale-95"
                  >
                    <span>Next</span>
                    <svg
                      className="w-5 h-5"
                      fill="none"
                      stroke="currentColor"
                      viewBox="0 0 24 24"
                    >
                      <path
                        strokeLinecap="round"
                        strokeLinejoin="round"
                        strokeWidth={2}
                        d="M9 5l7 7-7 7"
                      />
                    </svg>
                  </button>
                </div>
              )}

            <div className="flex justify-between items-start mb-6">
              <div>
                <h2 className="text-3xl font-bold text-gray-800 mb-2">
                  {viewingPlanSong.title}
                </h2>
                <p className="text-lg text-gray-600">
                  {viewingPlanSong.artist || viewingPlanSong.band}
                </p>
              </div>
              <button
                onClick={() => setViewingPlanSong(null)}
                className="text-gray-500 hover:text-gray-700 text-3xl font-bold"
              >
                ×
              </button>
            </div>

            {/* Embedded LyricModal Content */}
            <LyricModal
              modal={viewingPlanSong}
              setModal={setViewingPlanSong}
              onSave={async () => {
                await saveSong(viewingPlanSong.id, {
                  title: viewingPlanSong.title,
                  artist: viewingPlanSong.artist,
                  band: viewingPlanSong.band,
                  lyrics: viewingPlanSong.lyrics,
                  chords: viewingPlanSong.chords,
                  singer: viewingPlanSong.singer,
                });
                await load();
                // Trigger sync events for both songs and plans
                window.dispatchEvent(
                  new CustomEvent("songsChanged", {
                    detail: { id: viewingPlanSong.id },
                  })
                );
                window.dispatchEvent(new Event("plansChanged"));
              }}
              profileId={selectedProfileId}
              viewingPlan={viewingPlan}
              onNavigateNext={navigateToNextSong}
              onNavigatePrev={navigateToPrevSong}
            />

            {/* Back Button */}
            <div className="mt-6 pt-6 border-t border-gray-200">
              <button
                onClick={() => setViewingPlanSong(null)}
                className="px-6 py-3 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition-colors font-semibold flex items-center gap-2"
              >
                ← Back to Worship List
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Lyric Modal */}
      {lyricModal && (
        <LyricModal
          modal={lyricModal}
          setModal={setLyricModal}
          onSave={async () => {
            await saveSong(lyricModal.id, {
              title: lyricModal.title,
              artist: lyricModal.artist,
              band: lyricModal.band,
              lyrics: lyricModal.lyrics,
              chords: lyricModal.chords,
              singer: lyricModal.singer,
            });
            await load();
            // Trigger both plan and song change events for full sync
            window.dispatchEvent(
              new CustomEvent("songsChanged", { detail: { id: lyricModal.id } })
            );
            window.dispatchEvent(new Event("plansChanged"));
          }}
          profileId={null}
        />
      )}
    </div>
  );
}

function ExportDropdown() {
  const [plans, setPlans] = useState([]);
  const [showDropdown, setShowDropdown] = useState(false);

  useEffect(() => {
    loadPlans();
  }, []);

  async function loadPlans() {
    const p = await fetchPlans();
    setPlans(p || []);
  }

  function handleExport(planId) {
    window.open(exportPlanURL(planId), "_blank");
    setShowDropdown(false);
  }

  const dropdownRef = React.useRef(null);

  // Click outside to close
  React.useEffect(() => {
    const handleClickOutside = (event) => {
      if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
        setShowDropdown(false);
      }
    };
    document.addEventListener("mousedown", handleClickOutside);
    return () => document.removeEventListener("mousedown", handleClickOutside);
  }, []);

  return (
    <div ref={dropdownRef} style={{ position: "relative" }}>
      <button
        onClick={() => setShowDropdown(!showDropdown)}
        className="export-dropdown-btn"
        style={{
          padding: "0.5rem 0.85rem",
          background: "rgba(255,255,255,0.2)",
          color: "white",
          border: "none",
          borderRadius: "0.5rem",
          cursor: "pointer",
          fontWeight: "600",
          fontSize: "0.9rem",
          whiteSpace: "nowrap",
          pointerEvents: "auto",
        }}
      >
        📄 Export ▾
      </button>
      {showDropdown && plans.length > 0 && (
        <div
          style={{
            position: "absolute",
            top: "100%",
            right: 0,
            marginTop: 8,
            background: "white",
            borderRadius: 8,
            boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
            minWidth: 220,
            zIndex: 1002,
            pointerEvents: "auto",
          }}
        >
          <div
            style={{
              padding: "8px 12px",
              borderBottom: "1px solid #eee",
              fontSize: 11,
              color: "#888",
              fontWeight: "bold",
              textTransform: "uppercase",
            }}
          >
            Select Plan to Export
          </div>
          {plans.map((p) => (
            <div
              key={p.id}
              onClick={() => handleExport(p.id)}
              className="dropdown-item"
              style={{
                padding: "12px 16px",
                cursor: "pointer",
                borderBottom: "1px solid #eee",
                color: "#333",
                pointerEvents: "auto",
                userSelect: "none",
              }}
            >
              <div style={{ fontWeight: "bold" }}>{p.date}</div>
              <div style={{ fontSize: 11, color: "#666" }}>
                📄 Download setlist
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

function ProfileDropdown() {
  const navigate = useNavigate();
  const location = useLocation();
  const [profiles, setProfiles] = useState([]);
  const [showDropdown, setShowDropdown] = useState(false);
  const dropdownRef = useRef(null);

  // Load profiles once on mount
  useEffect(() => {
    fetchProfiles()
      .then((data) => {
        if (Array.isArray(data)) {
          setProfiles(data);
        }
      })
      .catch((err) => {
        console.error("Failed to load profiles:", err);
      });

    // Close dropdown when clicking outside
    function handleClickOutside(e) {
      if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
        setShowDropdown(false);
      }
    }
    document.addEventListener("mousedown", handleClickOutside);
    return () => document.removeEventListener("mousedown", handleClickOutside);
  }, []);

  // Get currently selected profile from URL
  const urlParams = new URLSearchParams(location.search);
  const currentProfileId =
    location.pathname === "/profile" ? urlParams.get("id") : null;
  const currentProfile = currentProfileId
    ? profiles.find((p) => p?.id?.toString() === currentProfileId)
    : null;

  function handleSelectProfile(profile) {
    setShowDropdown(false);
    navigate(`/profile?id=${profile.id}`);
  }

  const isOnProfilePage = location.pathname === "/profile";
  const buttonText =
    isOnProfilePage && currentProfile
      ? `👤 ${currentProfile.name} ▾`
      : "👤 Select Profile ▾";

  return (
    <div ref={dropdownRef} style={{ position: "relative" }}>
      <button
        onClick={() => setShowDropdown(!showDropdown)}
        className="profile-dropdown-btn"
        style={{
          padding: "0.5rem 0.85rem",
          background: "rgba(255,255,255,0.2)",
          color: "white",
          border: "none",
          borderRadius: "0.5rem",
          cursor: "pointer",
          fontWeight: "600",
          fontSize: "0.9rem",
          whiteSpace: "nowrap",
          pointerEvents: "auto",
        }}
      >
        {buttonText}
      </button>

      {showDropdown && profiles.length > 0 && (
        <div
          style={{
            position: "absolute",
            top: "calc(100% + 8px)",
            right: 0,
            background: "white",
            borderRadius: 8,
            boxShadow: "0 4px 20px rgba(0,0,0,0.2)",
            minWidth: 220,
            maxHeight: 400,
            overflowY: "auto",
            zIndex: 1002,
          }}
        >
          {profiles.map((profile) => {
            const isSelected = currentProfileId === profile.id?.toString();
            return (
              <div
                key={profile.id}
                onClick={() => handleSelectProfile(profile)}
                style={{
                  padding: "12px 16px",
                  cursor: "pointer",
                  borderBottom: "1px solid #f0f0f0",
                  backgroundColor: isSelected ? "#f8f9ff" : "white",
                  color: "#333",
                  fontWeight: isSelected ? "600" : "normal",
                }}
                onMouseEnter={(e) =>
                  !isSelected &&
                  (e.currentTarget.style.backgroundColor = "#f5f5f5")
                }
                onMouseLeave={(e) =>
                  !isSelected &&
                  (e.currentTarget.style.backgroundColor = "white")
                }
              >
                {isSelected && (
                  <span style={{ color: "#667eea", marginRight: 8 }}>✓</span>
                )}
                {profile.name}
              </div>
            );
          })}

          <Link
            to="/profile"
            style={{ textDecoration: "none" }}
            onClick={() => setShowDropdown(false)}
          >
            <div
              style={{
                padding: "12px 16px",
                cursor: "pointer",
                color: "#667eea",
                fontWeight: "600",
                textAlign: "center",
                borderTop: "2px solid #f0f0f0",
                backgroundColor: "white",
              }}
              onMouseEnter={(e) =>
                (e.currentTarget.style.backgroundColor = "#f8f9ff")
              }
              onMouseLeave={(e) =>
                (e.currentTarget.style.backgroundColor = "white")
              }
            >
              ⚙️ Manage Profiles
            </div>
          </Link>
        </div>
      )}
    </div>
  );
}

function DataSyncSection({ localMode, protocol, dnsHostname, port }) {
  const [syncing, setSyncing] = useState(false);
  const [syncResult, setSyncResult] = useState(null);
  const [syncType, setSyncType] = useState("full"); // full, upload, download

  async function handleSync() {
    setSyncing(true);
    setSyncResult(null);

    try {
      const customBase = `${protocol}://${dnsHostname}${
        port ? `:${port}` : ""
      }/api`;

      // Import sync functions
      const {
        fullSync,
        migrateLocalStorageToBackend,
        syncFromBackendToLocalStorage,
      } = await import("./migration");

      let result;
      if (syncType === "full") {
        result = await fullSync(customBase);
      } else if (syncType === "upload") {
        result = await migrateLocalStorageToBackend(customBase);
      } else {
        result = await syncFromBackendToLocalStorage(customBase);
      }

      setSyncResult(result);

      // Trigger data refresh events instead of full page reload
      if (result.success) {
        window.dispatchEvent(new Event("songsChanged"));
        window.dispatchEvent(new Event("plansChanged"));
        window.dispatchEvent(new CustomEvent("dataFullySynced"));
      }
    } catch (error) {
      setSyncResult({ success: false, error: error.message });
    } finally {
      setSyncing(false);
    }
  }

  if (localMode) return null; // Only show in online mode

  return (
    <div className="mt-6 p-6 bg-gradient-to-r from-green-50 to-blue-50 border-2 border-green-300 rounded-lg">
      <h3 className="text-xl font-bold mb-3 text-gray-800 flex items-center gap-2">
        <span>🔄</span> Data Synchronization
      </h3>
      <p className="text-sm text-gray-600 mb-4">
        Sync your data between this device and the backend server. Use this when
        switching devices or after adding songs on your phone.
      </p>

      <div className="space-y-3 mb-4">
        <label className="flex items-center gap-3 p-3 border-2 rounded-lg cursor-pointer hover:bg-white transition-all">
          <input
            type="radio"
            name="syncType"
            value="full"
            checked={syncType === "full"}
            onChange={(e) => setSyncType(e.target.value)}
            className="w-4 h-4"
          />
          <div>
            <div className="font-semibold">Full Sync (Recommended)</div>
            <div className="text-sm text-gray-600">
              Merge data from both local storage and backend server
            </div>
          </div>
        </label>

        <label className="flex items-center gap-3 p-3 border-2 rounded-lg cursor-pointer hover:bg-white transition-all">
          <input
            type="radio"
            name="syncType"
            value="download"
            checked={syncType === "download"}
            onChange={(e) => setSyncType(e.target.value)}
            className="w-4 h-4"
          />
          <div>
            <div className="font-semibold">Download from Server</div>
            <div className="text-sm text-gray-600">
              Pull all data from backend to this device
            </div>
          </div>
        </label>

        <label className="flex items-center gap-3 p-3 border-2 rounded-lg cursor-pointer hover:bg-white transition-all">
          <input
            type="radio"
            name="syncType"
            value="upload"
            checked={syncType === "upload"}
            onChange={(e) => setSyncType(e.target.value)}
            className="w-4 h-4"
          />
          <div>
            <div className="font-semibold">Upload to Server</div>
            <div className="text-sm text-gray-600">
              Push local data to backend server
            </div>
          </div>
        </label>
      </div>

      <button
        onClick={handleSync}
        disabled={syncing || !dnsHostname}
        className={`w-full px-6 py-4 rounded-lg font-bold text-white transition-all ${
          syncing || !dnsHostname
            ? "bg-gray-400 cursor-not-allowed"
            : "bg-gradient-to-r from-green-600 to-blue-600 hover:from-green-700 hover:to-blue-700 shadow-lg"
        }`}
      >
        {syncing ? "🔄 Syncing..." : "🔄 Start Sync"}
      </button>

      {syncResult && (
        <div
          className={`mt-4 p-4 rounded-lg border-2 ${
            syncResult.success
              ? "bg-green-50 border-green-500"
              : "bg-red-50 border-red-500"
          }`}
        >
          <div className="font-bold mb-2">
            {syncResult.success ? "✅ Sync Successful!" : "❌ Sync Failed"}
          </div>
          {syncResult.success && syncResult.upload && (
            <div className="text-sm space-y-1">
              <div>
                ⬆️ Uploaded: {JSON.stringify(syncResult.upload.migrated || {})}
              </div>
              {syncResult.download && (
                <div>
                  ⬇️ Downloaded:{" "}
                  {JSON.stringify(syncResult.download.synced || {})}
                </div>
              )}
            </div>
          )}
          {syncResult.success && syncResult.synced && (
            <div className="text-sm">
              Downloaded: {JSON.stringify(syncResult.synced)}
            </div>
          )}
          {syncResult.success && syncResult.migrated && (
            <div className="text-sm">
              Uploaded: {JSON.stringify(syncResult.migrated)}
            </div>
          )}
          {!syncResult.success && (
            <div className="text-sm text-red-700">{syncResult.error}</div>
          )}
          {syncResult.success && (
            <div className="text-sm text-gray-600 mt-2">
              Page will reload in 2 seconds...
            </div>
          )}
        </div>
      )}
    </div>
  );
}

/**
 * Biometric Authentication Settings Component
 */
function BiometricSettings() {
  const [biometricAvailable, setBiometricAvailable] = useState(false);
  const [credentials, setCredentials] = useState([]);
  const [loading, setLoading] = useState(true);
  const [registering, setRegistering] = useState(false);
  const [error, setError] = useState("");
  const [success, setSuccess] = useState("");

  useEffect(() => {
    checkBiometricAvailability();
    loadCredentials();
  }, []);

  async function checkBiometricAvailability() {
    try {
      const biometricAuth = await import("./biometricAuth");
      const result = await biometricAuth.isBiometricAvailable();
      setBiometricAvailable(result.available);
    } catch (err) {
      console.error("Error checking biometric availability:", err);
    }
  }

  async function loadCredentials() {
    setLoading(true);
    try {
      const storedUsername = localStorage.getItem("masterUsername") || "hop";
      const biometricAuth = await import("./biometricAuth");
      const result = await biometricAuth.getBiometricDevices(storedUsername);

      if (result.success) {
        setCredentials(result.credentials);
      }
    } catch (err) {
      console.error("Error loading credentials:", err);
    } finally {
      setLoading(false);
    }
  }

  async function registerDevice() {
    setRegistering(true);
    setError("");
    setSuccess("");

    try {
      const storedUsername = localStorage.getItem("masterUsername") || "hop";
      const biometricAuth = await import("./biometricAuth");
      const result = await biometricAuth.registerBiometric(storedUsername);

      if (result.success) {
        setSuccess("✅ Biometric authentication registered successfully!");
        await loadCredentials();
      } else {
        setError(`❌ Registration failed: ${result.error}`);
      }
    } catch (err) {
      setError(`❌ Registration error: ${err.message}`);
    } finally {
      setRegistering(false);
    }
  }

  async function toggleDevice(credentialId, currentlyEnabled) {
    try {
      const biometricAuth = await import("./biometricAuth");
      const result = await biometricAuth.toggleBiometricDevice(
        credentialId,
        !currentlyEnabled
      );

      if (result.success) {
        await loadCredentials();
      } else {
        setError(`Failed to toggle device: ${result.error}`);
      }
    } catch (err) {
      setError(`Error: ${err.message}`);
    }
  }

  async function deleteDevice(credentialId) {
    if (
      !window.confirm(
        "Are you sure you want to remove this device? You will need to re-register to use biometric authentication on this device."
      )
    ) {
      return;
    }

    try {
      const biometricAuth = await import("./biometricAuth");
      const result = await biometricAuth.deleteBiometricDevice(credentialId);

      if (result.success) {
        setSuccess("Device removed successfully");
        await loadCredentials();
      } else {
        setError(`Failed to delete device: ${result.error}`);
      }
    } catch (err) {
      setError(`Error: ${err.message}`);
    }
  }

  return (
    <div className="card mb-6">
      <h2 className="text-2xl font-bold mb-4 text-gray-800 flex items-center gap-2">
        <i className="bi bi-fingerprint" style={{ fontSize: "1.75rem" }}></i>
        <span>Biometric Authentication</span>
      </h2>

      <p className="text-gray-600 mb-4">
        Use fingerprint or Face ID to quickly and securely login to the app.
        Each device must be registered separately.
      </p>

      {/* HTTPS Warning */}
      {!window.isSecureContext && window.location.hostname !== "localhost" && (
        <div className="alert alert-warning mb-4">
          <i className="bi bi-exclamation-triangle-fill me-2"></i>
          <strong>HTTPS Required:</strong> Biometric authentication requires a
          secure connection (HTTPS).
          <br />
          <small>
            Current URL: {window.location.protocol}//{window.location.host}
            <br />
            Please access via: <strong>https://{window.location.host}</strong>
          </small>
        </div>
      )}

      {error && (
        <div className="alert alert-danger mb-4">
          {error}
          <button
            type="button"
            className="btn-close"
            onClick={() => setError("")}
          ></button>
        </div>
      )}

      {success && (
        <div className="alert alert-success mb-4">
          {success}
          <button
            type="button"
            className="btn-close"
            onClick={() => setSuccess("")}
          ></button>
        </div>
      )}

      {!biometricAvailable ? (
        <div className="p-4 bg-yellow-50 border-l-4 border-yellow-400 rounded">
          <div className="font-semibold text-gray-800">
            ⚠️ Biometric Authentication Not Available
          </div>
          <div className="text-sm text-gray-600 mt-2">
            Your device or browser doesn't support biometric authentication
            (fingerprint/Face ID). This feature requires:
          </div>
          <ul className="text-sm text-gray-600 mt-2 list-disc list-inside">
            <li>A device with fingerprint sensor or Face ID</li>
            <li>HTTPS connection (secure website)</li>
            <li>Modern browser (Chrome, Safari, Edge, Firefox)</li>
          </ul>
        </div>
      ) : (
        <>
          {/* Register New Device Button */}
          <button
            onClick={registerDevice}
            disabled={registering}
            className="btn btn-primary mb-4"
            style={{
              background: "linear-gradient(135deg, #10b981 0%, #059669 100%)",
              border: "none",
              padding: "12px 24px",
              fontSize: "1rem",
              fontWeight: "600",
            }}
          >
            {registering ? (
              <>
                <span className="spinner-border spinner-border-sm me-2"></span>
                Registering...
              </>
            ) : (
              <>
                <i className="bi bi-fingerprint me-2"></i>
                Register This Device
              </>
            )}
          </button>

          {/* Registered Devices List */}
          <div className="mt-4">
            <h3 className="text-lg font-bold mb-3 text-gray-800">
              Registered Devices ({credentials.length})
            </h3>

            {loading ? (
              <div className="text-center py-4">
                <span className="spinner-border"></span>
              </div>
            ) : credentials.length === 0 ? (
              <div className="p-4 bg-gray-50 border border-gray-300 rounded text-center">
                <p className="text-gray-600">
                  No devices registered yet. Click "Register This Device" above
                  to enable biometric login.
                </p>
              </div>
            ) : (
              <div className="space-y-3">
                {credentials.map((cred) => (
                  <div
                    key={cred.id}
                    className="p-4 border-2 border-gray-300 rounded-lg"
                    style={{
                      background: cred.enabled ? "#f0fdf4" : "#f9fafb",
                    }}
                  >
                    <div className="flex justify-between items-start">
                      <div className="flex-1">
                        <div className="font-bold text-gray-800 mb-1">
                          <i className="bi bi-phone me-2"></i>
                          {cred.device_name}
                        </div>
                        <div className="text-sm text-gray-600 mb-1">
                          Registered:{" "}
                          {new Date(cred.created_at).toLocaleDateString()}
                        </div>
                        {cred.last_used && (
                          <div className="text-xs text-gray-500">
                            Last used:{" "}
                            {new Date(cred.last_used).toLocaleString()}
                          </div>
                        )}
                        <div className="mt-2">
                          <span
                            className={`badge ${
                              cred.enabled ? "bg-success" : "bg-secondary"
                            }`}
                          >
                            {cred.enabled ? "✓ Enabled" : "✗ Disabled"}
                          </span>
                        </div>
                      </div>
                      <div className="flex gap-2">
                        <button
                          onClick={() => toggleDevice(cred.id, cred.enabled)}
                          className={`btn btn-sm ${
                            cred.enabled ? "btn-warning" : "btn-success"
                          }`}
                          title={cred.enabled ? "Disable" : "Enable"}
                        >
                          <i
                            className={`bi bi-${
                              cred.enabled ? "pause" : "play"
                            }-fill`}
                          ></i>
                        </button>
                        <button
                          onClick={() => deleteDevice(cred.id)}
                          className="btn btn-sm btn-danger"
                          title="Delete"
                        >
                          <i className="bi bi-trash-fill"></i>
                        </button>
                      </div>
                    </div>
                  </div>
                ))}
              </div>
            )}
          </div>

          {/* Information Box */}
          <div className="mt-4 p-4 bg-blue-50 border-l-4 border-blue-500 rounded">
            <div className="font-semibold text-gray-800 mb-2">
              <i className="bi bi-info-circle me-2"></i>
              How it works
            </div>
            <ul className="text-sm text-gray-700 space-y-1 list-disc list-inside">
              <li>
                Your biometric data (fingerprint/face) never leaves your device
              </li>
              <li>
                Only encrypted cryptographic keys are stored on the server
              </li>
              <li>Each device needs to be registered separately</li>
              <li>You can disable or remove devices anytime</li>
              <li>Biometric login is an alternative to password login</li>
            </ul>
          </div>
        </>
      )}
    </div>
  );
}

function Settings() {
  const [dnsHostname, setDnsHostname] = useState("");
  const [port, setPort] = useState("");
  const [protocol, setProtocol] = useState("https");
  const [saveSuccess, setSaveSuccess] = useState(false);
  const [localMode, setLocalMode] = useState(true);
  const [diagnosticRunning, setDiagnosticRunning] = useState(false);
  const [diagnosticResult, setDiagnosticResult] = useState(null);

  // Helper: persist settings immediately (used for auto-save on mode change)
  function persistSettings(updated) {
    localStorage.setItem("api_settings", JSON.stringify(updated));
  }

  useEffect(() => {
    // Load saved settings from api_settings
    const apiSettings = localStorage.getItem("api_settings");
    if (apiSettings) {
      try {
        const parsed = JSON.parse(apiSettings);
        setDnsHostname(parsed.hostname || "houseofprayer.ddns.net");
        setPort(parsed.port || "8080");
        setProtocol(parsed.protocol || "https");
        setLocalMode(parsed.useLocalStorage !== false);
      } catch (e) {}
    } else {
      // Default settings
      setDnsHostname("houseofprayer.ddns.net");
      setPort("8080");
      setProtocol("https");
      setLocalMode(false);
    }
  }, []);

  function saveSettings() {
    const apiSettings = {
      protocol: protocol,
      hostname: dnsHostname,
      port: port,
      useLocalStorage: localMode,
    };

    localStorage.setItem("api_settings", JSON.stringify(apiSettings));

    // Mark migration as needed if switching to backend mode
    if (!localMode) {
      localStorage.removeItem("data_migrated");
      // Attempt automatic migration: if backend is reachable and empty but local has data
      (async () => {
        try {
          // Fetch backend profiles & songs to see if empty
          const base = `${protocol}://${dnsHostname}:${port}/api`;
          const [profilesRes, songsRes] = await Promise.all([
            fetch(base + "/profiles").then((r) => (r.ok ? r.json() : [])),
            fetch(base + "/songs").then((r) => (r.ok ? r.json() : [])),
          ]);
          const backendEmpty =
            profilesRes.length === 0 && songsRes.length === 0;
          // Check local storage data using existing offline keys
          const localProfiles = localStorage.getItem("hop_profiles");
          const localSongs = localStorage.getItem("hop_songs");
          const hasLocalData =
            (localProfiles && localProfiles !== "[]") ||
            (localSongs && localSongs !== "[]");
          if (backendEmpty && hasLocalData) {
            try {
              const { migrateLocalStorageToBackend } = await import(
                "./migration"
              );
              const result = await migrateLocalStorageToBackend();
              if (result.success) {
                localStorage.setItem("data_migrated", "true");
              }
            } catch (err) {
              // Migration failed, continue anyway
            }
          }
        } catch (e) {
          // Backend check failed
        }
      })();
    }

    setSaveSuccess(true);
    setTimeout(() => {
      setSaveSuccess(false);
      // Reload to apply new settings
      window.location.reload();
    }, 1500);
  }

  function clearSettings() {
    if (window.confirm("Are you sure you want to reset to default settings?")) {
      const defaultSettings = {
        protocol: "https",
        hostname: "houseofprayer.ddns.net",
        port: "8080",
        useLocalStorage: false,
      };
      localStorage.setItem("api_settings", JSON.stringify(defaultSettings));
      setDnsHostname("houseofprayer.ddns.net");
      setPort("8080");
      setProtocol("https");
      setLocalMode(false);
      window.location.reload();
    }
  }

  const fullUrl = dnsHostname
    ? `${protocol}://${dnsHostname}${port ? `:${port}` : ""}`
    : "Not configured";

  async function cleanupDatabase() {
    if (
      !window.confirm(
        "This will permanently delete all songs with empty or 'Untitled' titles from the database. Continue?"
      )
    ) {
      return;
    }

    try {
      // Get all songs
      const allSongs = await searchLocalSongs("");
      const invalidSongs = allSongs.filter(
        (song) =>
          !song.title ||
          song.title.trim() === "" ||
          song.title.trim().toLowerCase() === "untitled"
      );

      if (invalidSongs.length === 0) {
        alert("No invalid songs found. Database is clean!");
        return;
      }

      // Delete each invalid song
      for (const song of invalidSongs) {
        await deleteSong(song.id);
      }

      alert(
        `Cleanup complete! Removed ${invalidSongs.length} songs with missing data.`
      );

      // Trigger sync event
      window.dispatchEvent(
        new CustomEvent("songsChanged", { detail: { cleanup: true } })
      );
    } catch (error) {
      alert(`Error cleaning database: ${error.message}`);
    }
  }

  async function runDiagnostics() {
    setDiagnosticRunning(true);
    setDiagnosticResult(null);

    const testUrl = `${protocol}://${dnsHostname}${port ? `:${port}` : ""}`;
    const lanUrl = `${protocol}://${hostname}${port ? `:${port}` : ""}`;

    const result = {
      timestamp: new Date().toLocaleString(),
      configUrl: testUrl,
      tests: [],
    };

    // Test 1: DNS Resolution
    try {
      const dnsTest = await fetch(
        `https://dns.google/resolve?name=${dnsHostname}`
      );
      const dnsData = await dnsTest.json();
      if (dnsData.Answer && dnsData.Answer.length > 0) {
        result.tests.push({
          name: "DNS Resolution",
          status: "✅ Success",
          message: `${dnsHostname} resolves to ${dnsData.Answer[0].data}`,
          details: dnsData.Answer[0].data,
        });
      } else {
        result.tests.push({
          name: "DNS Resolution",
          status: "❌ Failed",
          message: `${dnsHostname} does not resolve. Check No-IP DUC is running.`,
        });
      }
    } catch (err) {
      result.tests.push({
        name: "DNS Resolution",
        status: "⚠️ Error",
        message: `Could not check DNS: ${err.message}`,
      });
    }

    // Test 2: Localhost Connectivity (loopback)
    try {
      const localhostUrl = `http://localhost:${port || "8080"}/api/health`;
      const controller1 = new AbortController();
      const timeout1 = setTimeout(() => controller1.abort(), 3000);
      const response1 = await fetch(localhostUrl, {
        signal: controller1.signal,
      });
      clearTimeout(timeout1);
      if (response1.ok) {
        result.tests.push({
          name: "Localhost Connectivity",
          status: "✅ Success",
          message: `Backend responding on localhost:${port || "5000"}`,
        });
      } else {
        result.tests.push({
          name: "Localhost Connectivity",
          status: "⚠️ HTTP Error",
          message: `Localhost returned status ${response1.status}`,
        });
      }
    } catch (err) {
      result.tests.push({
        name: "Localhost Connectivity",
        status: "❌ Failed",
        message: "Backend not reachable on localhost. Is the server running?",
        details: err.message,
      });
    }

    // Test 3: Backend Connectivity (configured URL)
    const startTime = Date.now();
    try {
      const controller = new AbortController();
      const timeout = setTimeout(() => controller.abort(), 8000);
      const response = await fetch(testUrl, { signal: controller.signal });
      clearTimeout(timeout);
      const duration = Date.now() - startTime;

      if (response.ok) {
        const data = await response.json();
        result.tests.push({
          name: "Backend Connectivity",
          status: "✅ Success",
          message: `Server responded in ${duration}ms`,
          details: `Status: ${response.status}, Data: ${JSON.stringify(
            data
          ).substring(0, 100)}...`,
        });
      } else {
        result.tests.push({
          name: "Backend Connectivity",
          status: "⚠️ Partial",
          message: `Server reachable but returned ${response.status}`,
          details: await response.text().then((t) => t.substring(0, 200)),
        });
      }
    } catch (err) {
      const duration = Date.now() - startTime;
      if (err.name === "AbortError") {
        result.tests.push({
          name: "Backend Connectivity",
          status: "❌ Timeout",
          message: `No response after ${duration}ms. Server may be down or port not forwarded.`,
          details:
            "Check: 1) Backend running on host PC, 2) Router port forwarding, 3) Windows Firewall allows port 5000",
        });
      } else if (
        err.message.includes("Failed to fetch") ||
        err.message.includes("NetworkError")
      ) {
        result.tests.push({
          name: "Backend Connectivity",
          status: "❌ Failed",
          message: "Cannot reach server. Check network/firewall.",
          details: `Error: ${err.message}. Possible causes: CORS, router blocking, ISP CGNAT, or backend not listening on 0.0.0.0`,
        });
      } else {
        result.tests.push({
          name: "Backend Connectivity",
          status: "❌ Failed",
          message: err.message,
          details: err.stack?.substring(0, 300),
        });
      }
    }

    // Test 4: Local Network Test (attempt auto-detect host LAN IP)
    try {
      // Try window.location.hostname first (if already accessing via LAN IP)
      let localIp = window.location.hostname;
      const internalPattern =
        /^(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[0-1])\.)/;
      if (!internalPattern.test(localIp)) {
        // Fallback to user-provided known internal host
        localIp = "192.168.10.178";
      }
      const testPort = port || "8080";
      const localUrl = `http://${localIp}:${testPort}/api/profiles`;
      const controller = new AbortController();
      const timeout = setTimeout(() => controller.abort(), 3000);
      const response = await fetch(localUrl, { signal: controller.signal });
      clearTimeout(timeout);
      if (response.ok) {
        result.tests.push({
          name: "Local Network (LAN) Test",
          status: "✅ Success",
          message: `Backend reachable on LAN at ${localIp}:${testPort}`,
          details:
            "Backend responding locally. If external fails, focus on DNS/port forwarding/firewall/ISP.",
        });
      } else {
        result.tests.push({
          name: "Local Network (LAN) Test",
          status: "⚠️ HTTP Error",
          message: `LAN reachable but returned ${response.status}`,
        });
      }
    } catch (err) {
      result.tests.push({
        name: "Local Network (LAN) Test",
        status: "ℹ️ Skipped",
        message:
          "LAN probe failed (host not detected or backend not reachable on LAN)",
        details: err.message,
      });
    }

    setDiagnosticResult(result);
    setDiagnosticRunning(false);
  }

  return (
    <div className="container-responsive" style={{ maxWidth: 900 }}>
      <div className="fade-in">
        <h1 className="text-4xl font-bold mb-2 text-gray-800">Settings</h1>
        <p className="text-gray-600 mb-8">
          Configure system preferences and remote access
        </p>

        {/* Online Access Mode */}
        <div className="card mb-6">
          <h2 className="text-2xl font-bold mb-4 text-gray-800">Access Mode</h2>
          <div className="space-y-4">
            <div
              onClick={() => {
                // Switch to Local Mode, force port 5000 and save immediately
                const newSettings = {
                  protocol: "http",
                  hostname: "localhost",
                  port: "5000",
                  useLocalStorage: true,
                };
                setLocalMode(true);
                setDnsHostname("localhost");
                setPort("5000");
                setProtocol("http");
                persistSettings(newSettings);
              }}
              className={`p-4 border-2 rounded-lg cursor-pointer transition-all ${
                localMode
                  ? "border-purple-600 bg-purple-50"
                  : "border-gray-300 hover:border-gray-400"
              }`}
            >
              <div className="flex items-center gap-3">
                <div
                  className={`w-6 h-6 rounded-full border-2 flex items-center justify-center ${
                    localMode ? "border-purple-600" : "border-gray-400"
                  }`}
                >
                  {localMode && (
                    <div className="w-3 h-3 rounded-full bg-purple-600"></div>
                  )}
                </div>
                <div>
                  <div className="font-bold text-lg">Local Mode</div>
                  <div className="text-sm text-gray-600">
                    Access only on this device/network
                  </div>
                </div>
              </div>
            </div>

            <div
              onClick={() => {
                // Switch to Online Mode (do not auto-migrate here; user must Save)
                setLocalMode(false);
              }}
              className={`p-4 border-2 rounded-lg cursor-pointer transition-all ${
                !localMode
                  ? "border-purple-600 bg-purple-50"
                  : "border-gray-300 hover:border-gray-400"
              }`}
            >
              <div className="flex items-center gap-3">
                <div
                  className={`w-6 h-6 rounded-full border-2 flex items-center justify-center ${
                    !localMode ? "border-purple-600" : "border-gray-400"
                  }`}
                >
                  {!localMode && (
                    <div className="w-3 h-3 rounded-full bg-purple-600"></div>
                  )}
                </div>
                <div>
                  <div className="font-bold text-lg">
                    Online Mode (No-IP DNS)
                  </div>
                  <div className="text-sm text-gray-600">
                    Access from anywhere via custom domain
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>

        {/* DNS/Online Settings - Only show if Online Mode */}
        {!localMode && (
          <div className="card mb-6 fade-in">
            <h2 className="text-2xl font-bold mb-4 text-gray-800 flex items-center gap-2">
              <span>🌐</span> DNS / Online Settings
            </h2>
            <p className="text-gray-600 mb-6">
              Configure your No-IP dynamic DNS settings to access this system
              remotely from anywhere.
            </p>

            <div className="space-y-4">
              {/* Protocol Selector */}
              <div>
                <label className="block text-sm font-semibold text-gray-700 mb-2">
                  Protocol
                </label>
                <div className="flex gap-4">
                  <label className="flex items-center gap-2 cursor-pointer">
                    <input
                      type="radio"
                      value="http"
                      checked={protocol === "http"}
                      onChange={(e) => setProtocol(e.target.value)}
                      className="w-4 h-4"
                    />
                    <span>HTTP</span>
                  </label>
                  <label className="flex items-center gap-2 cursor-pointer">
                    <input
                      type="radio"
                      value="https"
                      checked={protocol === "https"}
                      onChange={(e) => setProtocol(e.target.value)}
                      className="w-4 h-4"
                    />
                    <span>HTTPS (Recommended)</span>
                  </label>
                </div>
              </div>

              {/* DNS Hostname */}
              <div>
                <label className="block text-sm font-semibold text-gray-700 mb-2">
                  No-IP Dynamic DNS Hostname *
                </label>
                <input
                  type="text"
                  value={dnsHostname}
                  onChange={(e) => setDnsHostname(e.target.value)}
                  placeholder="example: mychurch.no-ip.org"
                  className="w-full"
                />
                <p className="text-sm text-gray-500 mt-1">
                  Your No-IP hostname (without protocol or port)
                </p>
              </div>

              {/* Port Number */}
              <div>
                <label className="block text-sm font-semibold text-gray-700 mb-2">
                  Port Number (Optional)
                </label>
                <input
                  type="number"
                  value={port}
                  onChange={(e) => setPort(e.target.value)}
                  placeholder="e.g., 3000, 8080"
                  className="w-full"
                />
                <p className="text-sm text-gray-500 mt-1">
                  Leave empty for default ports (80 for HTTP, 443 for HTTPS)
                </p>
              </div>

              {/* Full URL Preview */}
              <div className="p-4 bg-gradient-to-r from-blue-50 to-purple-50 border-l-4 border-purple-600 rounded">
                <div className="text-sm font-semibold text-gray-700 mb-1">
                  Your Remote Access URL:
                </div>
                <div className="text-lg font-mono font-bold text-purple-700 break-all">
                  {fullUrl}
                </div>
              </div>

              {/* Instructions */}
              <div className="p-4 bg-yellow-50 border-l-4 border-yellow-400 rounded">
                <h3 className="font-bold text-gray-800 mb-2">
                  📋 Setup Instructions:
                </h3>
                <ol className="text-sm text-gray-700 space-y-1 list-decimal list-inside">
                  <li>
                    Create a free account at{" "}
                    <a
                      href="https://www.noip.com"
                      target="_blank"
                      rel="noopener noreferrer"
                      className="text-blue-600 underline"
                    >
                      NoIP.com
                    </a>
                  </li>
                  <li>Create a hostname (e.g., mychurch.no-ip.org)</li>
                  <li>
                    Install the No-IP DUC (Dynamic Update Client) on your
                    server/computer
                  </li>
                  <li>Configure port forwarding on your router (if needed)</li>
                  <li>Enter your hostname here and save settings</li>
                  <li>Access your system from anywhere using the URL above</li>
                </ol>
              </div>

              {/* Action Buttons */}
              <div className="flex gap-3 flex-wrap">
                <button
                  onClick={saveSettings}
                  className="btn btn-primary flex-1 min-w-[200px]"
                >
                  💾 Save DNS Settings
                </button>
                <button
                  onClick={clearSettings}
                  type="button"
                  className="btn btn-secondary"
                  aria-label="Clear DNS settings"
                >
                  🗑️ Clear Settings
                </button>
              </div>

              {saveSuccess && (
                <div className="p-4 bg-green-50 border-l-4 border-green-500 rounded fade-in">
                  <div className="flex items-center gap-2 text-green-800 font-semibold">
                    <span>✓</span>
                    <span>Settings saved successfully!</span>
                  </div>
                </div>
              )}

              {/* Data Sync Section */}
              <DataSyncSection
                localMode={localMode}
                protocol={protocol}
                dnsHostname={dnsHostname}
                port={port}
              />
            </div>
          </div>
        )}

        {/* Connectivity Diagnostics - Show if Online Mode */}
        {!localMode && (
          <div className="card mb-6 fade-in">
            <h2 className="text-2xl font-bold mb-4 text-gray-800 flex items-center gap-2">
              <span>🔧</span> Connectivity Diagnostics
            </h2>
            <p className="text-gray-600 mb-6">
              Run comprehensive tests to troubleshoot external access issues.
              This will check DNS resolution, backend connectivity, and firewall
              status.
            </p>

            <div className="space-y-4">
              {/* Run Diagnostics Button */}
              <button
                onClick={runDiagnostics}
                disabled={diagnosticRunning || !dnsHostname}
                className={`w-full px-6 py-4 rounded-lg font-semibold text-white transition-all ${
                  diagnosticRunning || !dnsHostname
                    ? "bg-gray-400 cursor-not-allowed"
                    : "bg-blue-600 hover:bg-blue-700 shadow-md"
                }`}
              >
                {diagnosticRunning
                  ? "🔄 Running Diagnostics..."
                  : "🔍 Run Connectivity Test"}
              </button>

              {/* Diagnostic Results */}
              {diagnosticResult && (
                <div className="p-6 bg-gray-50 border-2 border-gray-300 rounded-lg">
                  <div className="mb-4 pb-4 border-b border-gray-300">
                    <div className="font-bold text-lg text-gray-800 mb-1">
                      Diagnostic Report
                    </div>
                    <div className="text-sm text-gray-600">
                      {diagnosticResult.timestamp}
                    </div>
                    <div className="text-xs text-gray-500 mt-1 font-mono">
                      Testing: {diagnosticResult.configUrl}
                    </div>
                  </div>

                  <div className="space-y-4">
                    {diagnosticResult.tests.map((test, idx) => (
                      <div
                        key={idx}
                        className={`p-4 rounded-lg border-l-4 ${
                          test.status.startsWith("✅")
                            ? "bg-green-50 border-green-500"
                            : test.status.startsWith("❌")
                            ? "bg-red-50 border-red-500"
                            : test.status.startsWith("⚠️")
                            ? "bg-yellow-50 border-yellow-500"
                            : "bg-blue-50 border-blue-500"
                        }`}
                      >
                        <div className="font-bold text-gray-800 mb-1">
                          {test.name}
                        </div>
                        <div className="text-sm font-semibold mb-2">
                          {test.status}
                        </div>
                        <div className="text-sm text-gray-700 mb-2">
                          {test.message}
                        </div>
                        {test.details && (
                          <div className="text-xs text-gray-600 font-mono bg-white p-2 rounded mt-2 overflow-auto">
                            {test.details}
                          </div>
                        )}
                      </div>
                    ))}
                  </div>

                  {/* Troubleshooting Tips */}
                  <div className="mt-6 p-4 bg-blue-50 border-l-4 border-blue-500 rounded">
                    <div className="font-bold text-gray-800 mb-2">
                      💡 Common Solutions
                    </div>
                    <ul className="text-sm text-gray-700 space-y-2 list-disc list-inside">
                      <li>
                        <strong>DNS fails:</strong> Ensure No-IP Dynamic Update
                        Client (DUC) is running on your server
                      </li>
                      <li>
                        <strong>Timeout/Connection failed:</strong> Confirm
                        Windows Firewall inbound rule for current port (e.g.
                        {port || "5000"})
                      </li>
                      <li>
                        <strong>LAN works, external fails:</strong> Verify
                        router forwarding External {port || "8080"} →
                        192.168.10.178:{port || "8080"}
                      </li>
                      <li>
                        <strong>Backend not listening:</strong> Ensure server
                        binds to 0.0.0.0:{port || "8080"} (not 127.0.0.1)
                      </li>
                      <li>
                        <strong>ISP blocking:</strong> Some ISPs block
                        residential inbound traffic (CGNAT). Contact ISP or use
                        Cloudflare Tunnel
                      </li>
                    </ul>
                  </div>

                  {/* Windows Firewall Command */}
                  <div className="mt-4 p-4 bg-purple-50 border-l-4 border-purple-500 rounded">
                    <div className="font-bold text-gray-800 mb-2">
                      🪟 Windows Firewall Fix (Run on host PC)
                    </div>
                    <div className="text-sm text-gray-700 mb-2">
                      Open PowerShell as Administrator and run:
                    </div>
                    <div className="bg-gray-900 text-green-400 p-3 rounded font-mono text-xs overflow-auto">
                      New-NetFirewallRule -DisplayName "HouseOfPrayer-API"
                      -Direction Inbound -Protocol TCP -LocalPort 5000 -Action
                      Allow
                    </div>
                    <div className="text-xs text-gray-600 mt-2">
                      Then verify backend is listening with:{" "}
                      <code className="bg-white px-1 rounded">
                        netstat -ano | Select-String ":5000"
                      </code>
                    </div>
                  </div>
                </div>
              )}

              {/* Quick Reference Card */}
              {!diagnosticResult && (
                <div className="p-4 bg-gradient-to-r from-purple-50 to-blue-50 border-l-4 border-purple-500 rounded">
                  <div className="font-bold text-gray-800 mb-2">
                    📋 Pre-Flight Checklist
                  </div>
                  <ul className="text-sm text-gray-700 space-y-1 list-disc list-inside">
                    <li>No-IP DUC running and hostname updated</li>
                    <li>Backend server running on port {port || "5000"}</li>
                    <li>
                      Windows Firewall allows inbound TCP {port || "5000"}
                    </li>
                    <li>
                      Router forwards external {port || "5000"} →
                      192.168.10.178:{port || "5000"}
                    </li>
                    <li>
                      Server binds to 0.0.0.0:{port || "5000"} (not 127.0.0.1)
                    </li>
                    <li>Test from mobile data (not same Wi-Fi)</li>
                  </ul>
                </div>
              )}
            </div>
          </div>
        )}

        {/* Biometric Authentication Settings */}
        <BiometricSettings />

        {/* Data Management & Migration */}
        <div className="card mb-6">
          <h2 className="text-2xl font-bold mb-4 text-gray-800 flex items-center gap-2">
            <span>💾</span> Data Management
          </h2>

          {localMode ? (
            <>
              <p className="text-gray-600 mb-4">
                Your data (songs, profiles, worship lists) is stored locally on
                this device only.
              </p>
              <div className="space-y-3">
                <div className="p-4 bg-blue-50 border-l-4 border-blue-500 rounded">
                  <div className="font-semibold text-gray-800">
                    Local Storage Active
                  </div>
                  <div className="text-sm text-gray-600">
                    Data is automatically saved as you work, even without
                    internet connection.
                  </div>
                </div>
                <div className="p-4 bg-green-50 border-l-4 border-green-500 rounded">
                  <div className="font-semibold text-gray-800">
                    ✓ Works Offline
                  </div>
                  <div className="text-sm text-gray-600">
                    Full functionality on Android, iPhone, iPad, tablets,
                    laptops, and desktops.
                  </div>
                </div>
                <div className="p-4 bg-yellow-50 border-l-4 border-yellow-400 rounded">
                  <div className="font-semibold text-gray-800">
                    💡 Want Multi-Device Sync?
                  </div>
                  <div className="text-sm text-gray-600 mb-3">
                    Switch to <strong>Online Mode</strong> above to sync your
                    data across all devices in real-time.
                  </div>
                </div>
              </div>
            </>
          ) : (
            <>
              <p className="text-gray-600 mb-4">
                Your data is synced with the backend server for multi-device
                access.
              </p>
              <div className="space-y-3">
                <div className="p-4 bg-purple-50 border-l-4 border-purple-500 rounded">
                  <div className="font-semibold text-gray-800">
                    🌐 Backend Sync Active
                  </div>
                  <div className="text-sm text-gray-600">
                    Connected to: {protocol}://{dnsHostname}:{port}
                  </div>
                </div>
                <div className="p-4 bg-green-50 border-l-4 border-green-500 rounded">
                  <div className="font-semibold text-gray-800">
                    ✓ Real-Time Sync
                  </div>
                  <div className="text-sm text-gray-600">
                    Changes appear instantly on all connected devices via
                    WebSocket.
                  </div>
                </div>
                <div className="p-4 bg-blue-50 border-l-4 border-blue-500 rounded">
                  <div className="font-semibold text-gray-800 mb-2">
                    📦 Data Migration
                  </div>
                  <div className="text-sm text-gray-600 mb-3">
                    Have existing local data? Migrate it to the backend for
                    sharing across devices.
                  </div>
                  <button
                    onClick={async () => {
                      if (
                        window.confirm(
                          "Migrate all local data to backend server?"
                        )
                      ) {
                        try {
                          const { migrateLocalStorageToBackend } = await import(
                            "./migration.js"
                          );
                          const result = await migrateLocalStorageToBackend();
                          if (result.success) {
                            alert("✅ Migration successful! Reloading...");
                            localStorage.setItem("data_migrated", "true");
                            window.location.reload();
                          } else {
                            alert(`❌ Migration failed: ${result.error}`);
                          }
                        } catch (err) {
                          alert(`❌ Migration error: ${err.message}`);
                        }
                      }
                    }}
                    className="px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition-colors font-semibold"
                  >
                    🔄 Migrate Local Data to Backend
                  </button>
                  <button
                    onClick={async () => {
                      if (
                        window.confirm(
                          "Force re-migrate (will attempt to add missing profile songs & keys). Continue?"
                        )
                      ) {
                        try {
                          // Clear migration marker to allow fresh attempt
                          localStorage.removeItem("data_migrated");
                          const { migrateLocalStorageToBackend } = await import(
                            "./migration.js"
                          );
                          const result = await migrateLocalStorageToBackend();
                          if (result.success) {
                            alert(
                              "✅ Force Migration successful! Reloading..."
                            );
                            localStorage.setItem("data_migrated", "true");
                            window.location.reload();
                          } else {
                            alert(`❌ Force Migration failed: ${result.error}`);
                          }
                        } catch (err) {
                          alert(`❌ Force Migration error: ${err.message}`);
                        }
                      }
                    }}
                    className="mt-3 px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors font-semibold"
                  >
                    ⚙️ Force Full Migration (Associations)
                  </button>
                </div>
              </div>
            </>
          )}

          {/* Database Cleanup - Available in both modes */}
          <div className="mt-4 p-4 bg-red-50 border-l-4 border-red-500 rounded">
            <div className="font-semibold text-gray-800 mb-2">
              🗑️ Database Cleanup
            </div>
            <div className="text-sm text-gray-600 mb-3">
              Remove corrupted or empty songs from the database. This will
              permanently delete all songs with blank titles.
            </div>
            <button
              onClick={cleanupDatabase}
              className="px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors font-semibold"
            >
              🧹 Clean Database (Remove Empty Songs)
            </button>
          </div>
        </div>

        {/* Device Compatibility Info */}
        <div className="card">
          <h2 className="text-2xl font-bold mb-4 text-gray-800 flex items-center gap-2">
            <span>📱</span> Device Compatibility
          </h2>
          <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
            <div className="p-4 bg-gradient-to-br from-purple-50 to-blue-50 rounded-lg">
              <div className="text-3xl mb-2">📱</div>
              <div className="font-bold">Mobile Phones</div>
              <div className="text-sm text-gray-600">Android & iPhone</div>
            </div>
            <div className="p-4 bg-gradient-to-br from-blue-50 to-purple-50 rounded-lg">
              <div className="text-3xl mb-2">📲</div>
              <div className="font-bold">Tablets</div>
              <div className="text-sm text-gray-600">
                iPad & Android tablets
              </div>
            </div>
            <div className="p-4 bg-gradient-to-br from-purple-50 to-pink-50 rounded-lg">
              <div className="text-3xl mb-2">💻</div>
              <div className="font-bold">Laptops</div>
              <div className="text-sm text-gray-600">All modern browsers</div>
            </div>
            <div className="p-4 bg-gradient-to-br from-pink-50 to-purple-50 rounded-lg">
              <div className="text-3xl mb-2">🖥️</div>
              <div className="font-bold">Desktops</div>
              <div className="text-sm text-gray-600">
                Chrome, Firefox, Safari, Edge
              </div>
            </div>
          </div>
          <div className="mt-6 p-4 bg-gradient-to-r from-green-50 to-blue-50 border-l-4 border-green-500 rounded">
            <div className="font-bold text-gray-800 mb-2">
              ✓ Fully Responsive Design
            </div>
            <div className="text-sm text-gray-600">
              This application automatically adapts to your screen size, whether
              you're using a phone, tablet, laptop, or desktop. All features
              work seamlessly across all devices.
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

// Mobile Full-Page Worship Plan View Component
function MobileWorshipPlanView() {
  const navigate = useNavigate();
  const location = useLocation();
  const { plan, plans } = location.state || {};
  const [viewingPlanSong, setViewingPlanSong] = useState(null);

  if (!plan) {
    navigate("/");
    return null;
  }

  const navigateToNextSong = async () => {
    if (!plan.songs || !viewingPlanSong) return;
    const currentIndex = plan.songs.findIndex(
      (s) => s.id === viewingPlanSong.id
    );
    if (currentIndex < plan.songs.length - 1) {
      const nextSong = plan.songs[currentIndex + 1];
      const fullSong = await getSongMerged(nextSong.id);
      setViewingPlanSong(fullSong);
    }
  };

  const navigateToPrevSong = async () => {
    if (!plan.songs || !viewingPlanSong) return;
    const currentIndex = plan.songs.findIndex(
      (s) => s.id === viewingPlanSong.id
    );
    if (currentIndex > 0) {
      const prevSong = plan.songs[currentIndex - 1];
      const fullSong = await getSongMerged(prevSong.id);
      setViewingPlanSong(fullSong);
    }
  };

  // Navigate to song detail view on mobile
  const viewSongOnMobile = async (song) => {
    if (song?.id) {
      const fullSong = await getSongMerged(song.id);
      navigate("/view-worship-song", {
        state: { song: fullSong, plan, plans },
      });
    }
  };

  return (
    <div className="min-h-screen bg-gradient-to-br from-purple-50 to-blue-50 pb-24">
      {/* Content */}
      <div className="p-4 pt-6">
        <div className="bg-white rounded-2xl shadow-lg p-5 mb-4">
          <h2 className="text-2xl font-bold text-gray-800 mb-2">
            Worship List
          </h2>
          <div className="text-xl text-purple-600 font-semibold">
            {(() => {
              const [year, month, day] = plan.date.split("-");
              return new Date(year, month - 1, day).toLocaleDateString(
                "en-US",
                {
                  weekday: "long",
                  month: "long",
                  day: "numeric",
                  year: "numeric",
                }
              );
            })()}
          </div>
        </div>

        {/* Notes Section */}
        {plan.notes && (
          <div className="mb-4 p-4 bg-yellow-50 border-l-4 border-yellow-400 rounded-lg">
            <h3 className="text-sm font-semibold text-gray-700 mb-2">Notes</h3>
            <p className="text-gray-700 whitespace-pre-wrap">{plan.notes}</p>
          </div>
        )}

        {/* Song Lineup */}
        <div className="mb-4">
          <h3 className="text-lg font-semibold text-gray-800 mb-4">
            Song Lineup
          </h3>
          {plan.songs && plan.songs.length > 0 ? (
            <div className="space-y-3">
              {plan.songs.map((song, idx) => {
                const songTitle = song?.title || song?.name || "Untitled Song";
                const songArtist =
                  song?.artist || song?.band || song?.singer || "";

                return (
                  <div
                    key={song?.id || idx}
                    onClick={() => viewSongOnMobile(song)}
                    className="flex items-center gap-3 p-4 bg-gradient-to-r from-purple-50 to-blue-50 rounded-lg border border-purple-200 active:bg-purple-100 transition-all"
                  >
                    <div className="flex items-center justify-center w-10 h-10 bg-purple-600 text-white rounded-full font-bold text-lg flex-shrink-0">
                      {idx + 1}
                    </div>
                    <div className="flex-1 min-w-0">
                      <div className="font-bold text-gray-800 break-words text-base">
                        {songTitle}
                      </div>
                      {songArtist && (
                        <div className="text-gray-600 truncate text-sm">
                          {songArtist}
                        </div>
                      )}
                    </div>
                    <svg
                      className="w-6 h-6 text-purple-600 flex-shrink-0"
                      fill="none"
                      stroke="currentColor"
                      viewBox="0 0 24 24"
                    >
                      <path
                        strokeLinecap="round"
                        strokeLinejoin="round"
                        strokeWidth={2}
                        d="M9 5l7 7-7 7"
                      />
                    </svg>
                  </div>
                );
              })}
            </div>
          ) : (
            <p className="text-gray-500 text-center py-8">
              No songs added to this worship list yet.
            </p>
          )}
        </div>
      </div>

      {/* Bottom Fixed Navigation Bar - Narrow */}
      <div className="fixed bottom-0 left-0 right-0 z-50 bg-white border-t-2 border-gray-300 shadow-2xl">
        <div className="flex items-center justify-center px-4 py-2 max-w-screen-lg mx-auto">
          {/* Back Button - Returns to Home */}
          <button
            onClick={() => navigate("/")}
            className="flex items-center justify-center w-14 h-14 bg-purple-600 text-white rounded-full shadow-lg active:scale-95 transition-transform"
            title="Back to Home"
          >
            <svg
              className="w-7 h-7"
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={3}
                d="M15 19l-7-7 7-7"
              />
            </svg>
          </button>
        </div>
      </div>
    </div>
  );
}

// Mobile Full-Page Worship Song View Component
function MobileWorshipSongView() {
  const navigate = useNavigate();
  const location = useLocation();
  const { song, plan, plans } = location.state || {};
  const [isScrolled, setIsScrolled] = useState(false);

  if (!song) {
    navigate(-1);
    return null;
  }

  // Filter out metadata keywords from lyrics
  const filterLyrics = (lyrics) => {
    if (!lyrics) return lyrics;

    const metadataPatterns = [
      /\b(verse|chorus|bridge|intro|outro|pre-chorus|prechorus|interlude|refrain)\s*\d*\b/gi,
      /\[.*?\]/g, // Remove bracketed text like [Verse 1], [Chorus]
      /\(.*?\)/g, // Remove parenthetical text like (x2), (Repeat)
    ];

    let filtered = lyrics;
    metadataPatterns.forEach((pattern) => {
      filtered = filtered.replace(pattern, "");
    });

    // Clean up extra whitespace
    filtered = filtered.replace(/\n\s*\n\s*\n/g, "\n\n").trim();
    return filtered;
  };

  const navigateToNextSong = async () => {
    if (!plan?.songs) return;
    const currentIndex = plan.songs.findIndex((s) => s.id === song.id);
    if (currentIndex < plan.songs.length - 1) {
      const nextSong = plan.songs[currentIndex + 1];
      const fullSong = await getSongMerged(nextSong.id);
      navigate("/view-worship-song", {
        state: { song: fullSong, plan, plans },
        replace: true,
      });
    }
  };

  const navigateToPrevSong = async () => {
    if (!plan?.songs) return;
    const currentIndex = plan.songs.findIndex((s) => s.id === song.id);
    if (currentIndex > 0) {
      const prevSong = plan.songs[currentIndex - 1];
      const fullSong = await getSongMerged(prevSong.id);
      navigate("/view-worship-song", {
        state: { song: fullSong, plan, plans },
        replace: true,
      });
    }
  };

  const currentIndex = plan?.songs
    ? plan.songs.findIndex((s) => s.id === song.id)
    : -1;
  const hasPrevious = currentIndex > 0;
  const hasNext = currentIndex < (plan?.songs?.length || 0) - 1;

  // Track scroll position for showing mini nav buttons
  useEffect(() => {
    const handleScroll = () => {
      setIsScrolled(window.scrollY > 100);
    };

    window.addEventListener("scroll", handleScroll);
    return () => window.removeEventListener("scroll", handleScroll);
  }, []);

  return (
    <div className="min-h-screen bg-white pb-24">
      {/* Song position indicator - Top Left */}
      {plan && plan.songs && plan.songs.length > 1 && (
        <div className="fixed top-4 left-4 z-40 bg-purple-600 text-white px-3 py-1.5 rounded-full text-sm font-bold shadow-lg">
          {currentIndex + 1} / {plan.songs.length}
        </div>
      )}

      {/* Song Content - MobileWorshipSongView */}
      <div className="p-5 pt-16">
        <div className="mb-6">
          <h1 className="text-3xl font-bold text-gray-900 mb-2">
            {song.title || "Untitled"}
          </h1>
          {(song.artist || song.band) && (
            <p className="text-lg text-gray-600">{song.artist || song.band}</p>
          )}
          {song.key && (
            <div className="mt-2">
              <span className="inline-block px-3 py-1 bg-purple-100 text-purple-800 rounded-full text-sm font-semibold">
                Key: {song.key}
              </span>
            </div>
          )}
          {(song.chord_progression ||
            (song.chords && song.chords.includes(" - "))) && (
            <div className="mt-2">
              <div className="text-sm text-gray-600 font-semibold">
                Chord Progression:
              </div>
              <div className="text-purple-600 font-bold text-base">
                {song.chord_progression || song.chords}
              </div>
            </div>
          )}
        </div>

        {song.lyrics ? (
          <div className="mb-8">
            <h3 className="text-lg font-semibold text-gray-800 mb-3">
              Song Sheet
            </h3>
            <div className="whitespace-pre-wrap text-gray-700 leading-relaxed text-lg">
              {song.chords
                ? // Display chords above lyrics line by line
                  song.lyrics.split("\n").map((lyricsLine, idx) => {
                    const chordLine = song.chords.split("\n")[idx] || "";
                    const filteredLyrics = filterLyrics(lyricsLine);
                    return (
                      <div key={idx} className="mb-3">
                        {chordLine && (
                          <div className="font-bold mb-1 text-purple-600 text-base">
                            {chordLine}
                          </div>
                        )}
                        <div className="text-gray-800">
                          {filteredLyrics || "\u00A0"}
                        </div>
                      </div>
                    );
                  })
                : // No chords - show filtered lyrics
                  filterLyrics(song.lyrics)}
            </div>
          </div>
        ) : (
          <p className="text-gray-500 text-center py-8">
            No lyrics or chords available for this song.
          </p>
        )}
      </div>

      {/* Bottom Fixed Navigation Bar - Narrow */}
      <div className="fixed bottom-0 left-0 right-0 z-50 bg-white border-t-2 border-gray-300 shadow-2xl">
        <div className="flex items-center justify-center px-4 py-2 max-w-screen-lg mx-auto gap-4">
          {/* Navigation Buttons (Previous/Next) - Only show if multiple songs */}
          {plan && plan.songs && plan.songs.length > 1 && (
            <>
              <button
                onClick={navigateToPrevSong}
                disabled={!hasPrevious}
                className="flex items-center justify-center w-11 h-11 bg-blue-600 text-white rounded-full shadow-md disabled:bg-gray-300 disabled:cursor-not-allowed active:scale-95 transition-all"
                title="Previous Song"
              >
                <svg
                  className="w-5 h-5"
                  fill="none"
                  stroke="currentColor"
                  viewBox="0 0 24 24"
                >
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    strokeWidth={2.5}
                    d="M15 19l-7-7 7-7"
                  />
                </svg>
              </button>

              <button
                onClick={navigateToNextSong}
                disabled={!hasNext}
                className="flex items-center justify-center w-11 h-11 bg-blue-600 text-white rounded-full shadow-md disabled:bg-gray-300 disabled:cursor-not-allowed active:scale-95 transition-all"
                title="Next Song"
              >
                <svg
                  className="w-5 h-5"
                  fill="none"
                  stroke="currentColor"
                  viewBox="0 0 24 24"
                >
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    strokeWidth={2.5}
                    d="M9 5l7 7-7 7"
                  />
                </svg>
              </button>
            </>
          )}

          {/* Back Button - Returns to Worship List */}
          <button
            onClick={() => navigate(-1)}
            className="flex items-center justify-center w-14 h-14 bg-purple-600 text-white rounded-full shadow-lg active:scale-95 transition-transform"
            title="Back to Worship List"
          >
            <svg
              className="w-7 h-7"
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={3}
                d="M15 19l-7-7 7-7"
              />
            </svg>
          </button>
        </div>
      </div>
    </div>
  );
}

// Mobile Full-Page Database Song View Component
function MobileDatabaseSongView() {
  const navigate = useNavigate();
  const location = useLocation();
  const { song: initialSong } = location.state || {};
  const [song, setSong] = useState(initialSong);
  const [currentKey, setCurrentKey] = useState(song?.key || "C");
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
  const [isEditing, setIsEditing] = useState(false);
  const [isGenerating, setIsGenerating] = useState(false);

  if (!song) {
    navigate("/database");
    return null;
  }

  // Filter out metadata keywords from lyrics
  const filterLyrics = (lyrics) => {
    if (!lyrics) return lyrics;

    const metadataPatterns = [
      /\b(verse|chorus|bridge|intro|outro|pre-chorus|prechorus|interlude|refrain)\s*\d*\b/gi,
      /\[.*?\]/g,
      /\(.*?\)/g,
    ];

    let filtered = lyrics;
    metadataPatterns.forEach((pattern) => {
      filtered = filtered.replace(pattern, "");
    });

    filtered = filtered.replace(/\n\s*\n\s*\n/g, "\n\n").trim();
    return filtered;
  };

  // Chord progression patterns for each key
  const getChordProgression = (key) => {
    const progressions = {
      C: ["C", "Am", "F", "G", "Dm", "Em"],
      "C#": ["C#", "A#m", "F#", "G#", "D#m", "Fm"],
      D: ["D", "Bm", "G", "A", "Em", "F#m"],
      "D#": ["D#", "Cm", "G#", "A#", "Fm", "Gm"],
      E: ["E", "C#m", "A", "B", "F#m", "G#m"],
      F: ["F", "Dm", "Bb", "C", "Gm", "Am"],
      "F#": ["F#", "D#m", "B", "C#", "G#m", "A#m"],
      G: ["G", "Em", "C", "D", "Am", "Bm"],
      "G#": ["G#", "Fm", "C#", "D#", "A#m", "Cm"],
      A: ["A", "F#m", "D", "E", "Bm", "C#m"],
      "A#": ["A#", "Gm", "D#", "F", "Cm", "Dm"],
      B: ["B", "G#m", "E", "F#", "C#m", "D#m"],
    };
    return progressions[key] || progressions["C"];
  };

  // Generate chords above lyrics - STORES CHORDS SEPARATELY FROM LYRICS
  const handleKeyGenerate = async () => {
    setIsGenerating(true);
    try {
      const progression = getChordProgression(currentKey);
      const lyrics = song.lyrics || "";
      const lines = lyrics.split("\n");

      // Build chords line-by-line matching lyrics structure
      let chordLines = [];
      let chordIndex = 0;

      // Section headers to exclude from chord assignment
      const sectionHeaders =
        /^(\[?(verse|chorus|bridge|intro|outro|pre-chorus|prechorus|interlude|refrain|lyrics|tag|ending|coda)\]?:?)/i;

      for (let i = 0; i < lines.length; i++) {
        const line = lines[i].trim();

        // Empty line - add empty chord line
        if (!line) {
          chordLines.push("");
          continue;
        }

        // Section header - no chord
        if (sectionHeaders.test(line)) {
          chordLines.push("");
          continue;
        }

        // Assign chord to lyric line (every 2 lines gets a chord)
        if (i % 2 === 0) {
          const chord = progression[chordIndex % progression.length];
          chordLines.push(chord);
          chordIndex++;
        } else {
          chordLines.push("");
        }
      }

      // Update song with SEPARATE chords and chord progression
      const updatedSong = {
        ...song,
        key: currentKey,
        chords: chordLines.join("\n"), // Line-by-line chords
        chord_progression: progression.join(" - "), // Summary progression
      };

      // Save to database
      const response = await fetch(`/api/songs/${song.id}`, {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(updatedSong),
      });

      if (response.ok) {
        setSong(updatedSong);
        // Dispatch sync events to update other views
        window.dispatchEvent(
          new CustomEvent("songsChanged", { detail: { id: song.id } })
        );
        window.dispatchEvent(new Event("plansChanged"));
        alert("Chords generated and saved successfully!");
      } else {
        const errorText = await response.text();
        console.error("Failed to save:", errorText);
        alert("Failed to save chords - " + response.status);
      }
    } catch (error) {
      console.error("Error generating chords:", error);
      alert("Error generating chords: " + error.message);
    } finally {
      setIsGenerating(false);
    }
  };

  const transposeChord = (chord, steps) => {
    const notes = [
      "C",
      "C#",
      "D",
      "D#",
      "E",
      "F",
      "F#",
      "G",
      "G#",
      "A",
      "A#",
      "B",
    ];
    const match = chord.match(/^([A-G]#?)(.*)$/);
    if (!match) return chord;

    const [, root, suffix] = match;
    const index = notes.indexOf(root);
    if (index === -1) return chord;

    const newIndex = (index + steps + 12) % 12;
    return notes[newIndex] + suffix;
  };

  const handleTranspose = (steps) => {
    const notes = [
      "C",
      "C#",
      "D",
      "D#",
      "E",
      "F",
      "F#",
      "G",
      "G#",
      "A",
      "A#",
      "B",
    ];
    const currentIndex = notes.indexOf(currentKey);
    const newIndex = (currentIndex + steps + 12) % 12;
    setCurrentKey(notes[newIndex]);
  };

  const handleDelete = async () => {
    if (song.id) {
      await deleteSong(song.id);
      navigate("/database");
    }
  };

  const keys = [
    "C",
    "C#",
    "D",
    "D#",
    "E",
    "F",
    "F#",
    "G",
    "G#",
    "A",
    "A#",
    "B",
  ];

  return (
    <div className="min-h-screen bg-white pb-24">
      {/* Top Action Bar */}
      <div className="sticky top-0 z-50 bg-gradient-to-r from-purple-600 to-blue-600 shadow-lg">
        <div className="px-4 py-3 flex items-center justify-between gap-2 overflow-x-auto">
          {/* Key Selector - Taller */}
          <select
            value={currentKey}
            onChange={(e) => setCurrentKey(e.target.value)}
            className="px-4 py-3 bg-white text-gray-800 rounded-lg font-semibold text-base shadow-md focus:outline-none focus:ring-2 focus:ring-white min-h-[48px]"
          >
            {keys.map((k) => (
              <option key={k} value={k}>
                {k}
              </option>
            ))}
          </select>

          {isEditing ? (
            <>
              {/* Key Generate Button (only in edit mode) */}
              <button
                onClick={handleKeyGenerate}
                disabled={isGenerating}
                className="px-3 py-3 bg-green-500 text-white rounded-lg font-semibold text-sm shadow-md active:scale-95 transition-transform whitespace-nowrap disabled:opacity-50"
              >
                {isGenerating ? "Generating..." : "Generate"}
              </button>

              {/* Transpose Down */}
              <button
                onClick={() => handleTranspose(-1)}
                className="px-3 py-3 bg-white text-gray-800 rounded-lg font-semibold text-sm shadow-md active:scale-95 transition-transform whitespace-nowrap"
                title="Transpose down 1 semitone"
              >
                ♭
              </button>

              {/* Transpose Up */}
              <button
                onClick={() => handleTranspose(1)}
                className="px-3 py-3 bg-white text-gray-800 rounded-lg font-semibold text-sm shadow-md active:scale-95 transition-transform whitespace-nowrap"
                title="Transpose up 1 semitone"
              >
                ♯
              </button>

              {/* Save/Done Button */}
              <button
                onClick={() => setIsEditing(false)}
                className="px-3 py-3 bg-blue-500 text-white rounded-lg font-semibold text-sm shadow-md active:scale-95 transition-transform whitespace-nowrap"
              >
                Done
              </button>
            </>
          ) : (
            <>
              {/* Edit Button */}
              <button
                onClick={() => setIsEditing(true)}
                className="px-3 py-3 bg-yellow-500 text-white rounded-lg font-semibold text-sm shadow-md active:scale-95 transition-transform whitespace-nowrap"
              >
                Edit
              </button>

              {/* Delete Button */}
              <button
                onClick={() => setShowDeleteConfirm(true)}
                className="px-3 py-3 bg-red-600 text-white rounded-lg font-semibold text-sm shadow-md active:scale-95 transition-transform whitespace-nowrap"
              >
                Delete
              </button>
            </>
          )}
        </div>
      </div>

      {/* Song Content - MobileDatabaseSongView */}
      <div className="p-5">
        <div className="mb-6">
          <h1 className="text-3xl font-bold text-gray-900 mb-2">
            {song.title || "Untitled"}
          </h1>
          {(song.artist || song.band) && (
            <p className="text-lg text-gray-600">{song.artist || song.band}</p>
          )}
          {song.key && (
            <div className="mt-2">
              <span className="inline-block px-3 py-1 bg-purple-100 text-purple-800 rounded-full text-sm font-semibold">
                Key: {song.key}
              </span>
            </div>
          )}
          {(song.chord_progression ||
            (song.chords && song.chords.includes(" - "))) && (
            <div className="mt-2">
              <div className="text-sm text-gray-600 font-semibold">
                Chord Progression:
              </div>
              <div className="text-purple-600 font-bold text-base">
                {song.chord_progression || song.chords}
              </div>
            </div>
          )}
        </div>

        {song.lyrics ? (
          <div className="mb-8">
            <div className="whitespace-pre-wrap text-gray-700 leading-relaxed text-lg">
              {song.chords
                ? // Display chords above lyrics line by line
                  song.lyrics.split("\n").map((lyricsLine, idx) => {
                    const chordLine = song.chords.split("\n")[idx] || "";
                    return (
                      <div key={idx} className="mb-3">
                        {chordLine && (
                          <div className="font-bold mb-1 text-purple-600 text-base">
                            {chordLine}
                          </div>
                        )}
                        <div className="text-gray-800">
                          {lyricsLine || "\u00A0"}
                        </div>
                      </div>
                    );
                  })
                : // No chords - just show lyrics
                  song.lyrics}
            </div>
          </div>
        ) : (
          <p className="text-gray-500 text-center py-8">
            No lyrics available for this song.
          </p>
        )}
      </div>

      {/* Bottom Fixed Navigation Bar - Narrower */}
      <div className="fixed bottom-0 left-0 right-0 z-50 bg-white border-t-2 border-gray-300 shadow-2xl">
        <div className="flex items-center justify-between px-6 py-2">
          {/* Back Button */}
          <button
            onClick={() => navigate(-1)}
            className="flex items-center justify-center w-12 h-12 bg-purple-600 text-white rounded-full shadow-lg active:scale-95 transition-transform"
          >
            <svg
              className="w-6 h-6"
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2.5}
                d="M15 19l-7-7 7-7"
              />
            </svg>
          </button>

          {/* Close Button - Bigger X */}
          <button
            onClick={() => navigate("/database")}
            className="flex items-center justify-center w-14 h-14 bg-red-600 text-white rounded-full shadow-lg active:scale-95 transition-transform text-3xl font-bold leading-none"
          >
            ×
          </button>
        </div>
      </div>

      {/* Delete Confirmation Modal */}
      {showDeleteConfirm && (
        <div className="fixed inset-0 z-[100] bg-black bg-opacity-50 flex items-center justify-center p-4">
          <div className="bg-white rounded-2xl p-6 max-w-sm w-full shadow-2xl">
            <h3 className="text-xl font-bold text-gray-800 mb-3">
              Confirm Delete
            </h3>
            <p className="text-gray-600 mb-6">
              Are you sure you want to delete "{song.title}"? This cannot be
              undone.
            </p>
            <div className="flex gap-3">
              <button
                onClick={() => setShowDeleteConfirm(false)}
                className="flex-1 px-4 py-3 bg-gray-500 text-white rounded-lg font-semibold active:scale-95 transition-transform"
              >
                Cancel
              </button>
              <button
                onClick={handleDelete}
                className="flex-1 px-4 py-3 bg-red-600 text-white rounded-lg font-semibold active:scale-95 transition-transform"
              >
                Delete
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

// Mobile Full-Page Profile Song View Component
function MobileProfileSongView() {
  const navigate = useNavigate();
  const location = useLocation();
  const { song: initialSong } = location.state || {};
  const [song, setSong] = useState(initialSong);
  const [currentKey, setCurrentKey] = useState(initialSong?.key || "C");
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
  const [isEditing, setIsEditing] = useState(false);
  const [isGenerating, setIsGenerating] = useState(false);

  if (!song) {
    navigate("/profile");
    return null;
  }

  // Chord progression patterns for each key
  const getChordProgression = (key) => {
    const progressions = {
      C: ["C", "Am", "F", "G", "Dm", "Em"],
      "C#": ["C#", "A#m", "F#", "G#", "D#m", "Fm"],
      D: ["D", "Bm", "G", "A", "Em", "F#m"],
      "D#": ["D#", "Cm", "G#", "A#", "Fm", "Gm"],
      E: ["E", "C#m", "A", "B", "F#m", "G#m"],
      F: ["F", "Dm", "Bb", "C", "Gm", "Am"],
      "F#": ["F#", "D#m", "B", "C#", "G#m", "A#m"],
      G: ["G", "Em", "C", "D", "Am", "Bm"],
      "G#": ["G#", "Fm", "C#", "D#", "A#m", "Cm"],
      A: ["A", "F#m", "D", "E", "Bm", "C#m"],
      "A#": ["A#", "Gm", "D#", "F", "Cm", "Dm"],
      B: ["B", "G#m", "E", "F#", "C#m", "D#m"],
    };
    return progressions[key] || progressions["C"];
  };

  // Generate chords above lyrics - STORES CHORDS SEPARATELY FROM LYRICS
  const handleKeyGenerate = async () => {
    setIsGenerating(true);
    try {
      const progression = getChordProgression(currentKey);
      const lyrics = song.lyrics || "";
      const lines = lyrics.split("\n");

      // Build chords line-by-line matching lyrics structure
      let chordLines = [];
      let chordIndex = 0;

      // Section headers to exclude from chord assignment
      const sectionHeaders =
        /^(\[?(verse|chorus|bridge|intro|outro|pre-chorus|prechorus|interlude|refrain|lyrics|tag|ending|coda)\]?:?)/i;

      for (let i = 0; i < lines.length; i++) {
        const line = lines[i].trim();

        // Empty line - add empty chord line
        if (!line) {
          chordLines.push("");
          continue;
        }

        // Section header - no chord
        if (sectionHeaders.test(line)) {
          chordLines.push("");
          continue;
        }

        // Assign chord to lyric line (every 2 lines gets a chord)
        if (i % 2 === 0) {
          const chord = progression[chordIndex % progression.length];
          chordLines.push(chord);
          chordIndex++;
        } else {
          chordLines.push("");
        }
      }

      // Update song with SEPARATE chords and chord progression
      const updatedSong = {
        ...song,
        key: currentKey,
        chords: chordLines.join("\n"), // Line-by-line chords
        chord_progression: progression.join(" - "), // Summary progression
      };

      // Save to database
      const response = await fetch(`/api/songs/${song.id}`, {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(updatedSong),
      });

      if (response.ok) {
        setSong(updatedSong);
        // Dispatch sync events to update other views
        window.dispatchEvent(
          new CustomEvent("songsChanged", { detail: { id: song.id } })
        );
        window.dispatchEvent(new Event("plansChanged"));
        alert("Chords generated and saved successfully!");
      } else {
        const errorText = await response.text();
        console.error("Failed to save:", errorText);
        alert("Failed to save chords - " + response.status);
      }
    } catch (error) {
      console.error("Error generating chords:", error);
      alert("Error generating chords: " + error.message);
    } finally {
      setIsGenerating(false);
    }
  };

  const handleTranspose = (steps) => {
    const notes = [
      "C",
      "C#",
      "D",
      "D#",
      "E",
      "F",
      "F#",
      "G",
      "G#",
      "A",
      "A#",
      "B",
    ];
    const currentIndex = notes.indexOf(currentKey);
    const newIndex = (currentIndex + steps + 12) % 12;
    setCurrentKey(notes[newIndex]);
  };

  const keys = [
    "C",
    "C#",
    "D",
    "D#",
    "E",
    "F",
    "F#",
    "G",
    "G#",
    "A",
    "A#",
    "B",
  ];

  return (
    <div className="min-h-screen bg-white pb-24">
      {/* Top Action Bar - MobileProfileSongView */}
      <div className="sticky top-0 z-50 bg-gradient-to-r from-purple-600 to-blue-600 shadow-lg">
        <div className="px-4 py-3 flex items-center justify-between gap-2 overflow-x-auto">
          {/* Key Selector - Taller */}
          <select
            value={currentKey}
            onChange={(e) => setCurrentKey(e.target.value)}
            className="px-4 py-3 bg-white text-gray-800 rounded-lg font-semibold text-base shadow-md focus:outline-none focus:ring-2 focus:ring-white min-h-[48px]"
          >
            {keys.map((k) => (
              <option key={k} value={k}>
                {k}
              </option>
            ))}
          </select>

          {isEditing ? (
            <>
              {/* Key Generate Button (only in edit mode) */}
              <button
                onClick={handleKeyGenerate}
                disabled={isGenerating}
                className="px-3 py-3 bg-green-500 text-white rounded-lg font-semibold text-sm shadow-md active:scale-95 transition-transform whitespace-nowrap disabled:opacity-50"
              >
                {isGenerating ? "Generating..." : "Generate"}
              </button>

              {/* Transpose Down */}
              <button
                onClick={() => handleTranspose(-1)}
                className="px-3 py-3 bg-white text-gray-800 rounded-lg font-semibold text-sm shadow-md active:scale-95 transition-transform whitespace-nowrap"
                title="Transpose down 1 semitone"
              >
                ♭
              </button>

              {/* Transpose Up */}
              <button
                onClick={() => handleTranspose(1)}
                className="px-3 py-3 bg-white text-gray-800 rounded-lg font-semibold text-sm shadow-md active:scale-95 transition-transform whitespace-nowrap"
                title="Transpose up 1 semitone"
              >
                ♯
              </button>

              {/* Save/Done Button */}
              <button
                onClick={() => setIsEditing(false)}
                className="px-3 py-3 bg-blue-500 text-white rounded-lg font-semibold text-sm shadow-md active:scale-95 transition-transform whitespace-nowrap"
              >
                Done
              </button>
            </>
          ) : (
            <>
              {/* Edit Button */}
              <button
                onClick={() => setIsEditing(true)}
                className="px-3 py-3 bg-yellow-500 text-white rounded-lg font-semibold text-sm shadow-md active:scale-95 transition-transform whitespace-nowrap"
              >
                Edit
              </button>
            </>
          )}
        </div>
      </div>

      {/* Song Content - MobileProfileSongView */}
      <div className="p-5">
        <div className="mb-6">
          <h1 className="text-3xl font-bold text-gray-900 mb-2">
            {song.title || "Untitled"}
          </h1>
          {(song.artist || song.band) && (
            <p className="text-lg text-gray-600">{song.artist || song.band}</p>
          )}
          {song.key && (
            <div className="mt-2">
              <span className="inline-block px-3 py-1 bg-purple-100 text-purple-800 rounded-full text-sm font-semibold">
                Key: {song.key}
              </span>
            </div>
          )}
          {(song.chord_progression ||
            (song.chords && song.chords.includes(" - "))) && (
            <div className="mt-2">
              <div className="text-sm text-gray-600 font-semibold">
                Chord Progression:
              </div>
              <div className="text-purple-600 font-bold text-base">
                {song.chord_progression || song.chords}
              </div>
            </div>
          )}
        </div>

        {song.lyrics ? (
          <div className="mb-8">
            <div className="whitespace-pre-wrap text-gray-700 leading-relaxed text-lg">
              {song.chords
                ? // Display chords above lyrics line by line
                  song.lyrics.split("\n").map((lyricsLine, idx) => {
                    const chordLine = song.chords.split("\n")[idx] || "";
                    return (
                      <div key={idx} className="mb-3">
                        {chordLine && (
                          <div className="font-bold mb-1 text-purple-600 text-base">
                            {chordLine}
                          </div>
                        )}
                        <div className="text-gray-800">
                          {lyricsLine || "\u00A0"}
                        </div>
                      </div>
                    );
                  })
                : // No chords - just show lyrics
                  song.lyrics}
            </div>
          </div>
        ) : (
          <p className="text-gray-500 text-center py-8">
            No lyrics available for this song.
          </p>
        )}
      </div>

      {/* Bottom Fixed Navigation Bar - Narrower */}
      <div className="fixed bottom-0 left-0 right-0 z-50 bg-white border-t-2 border-gray-300 shadow-2xl">
        <div className="flex items-center justify-between px-6 py-2">
          {/* Back Button */}
          <button
            onClick={() => navigate(-1)}
            className="flex items-center justify-center w-12 h-12 bg-purple-600 text-white rounded-full shadow-lg active:scale-95 transition-transform"
          >
            <svg
              className="w-6 h-6"
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2.5}
                d="M15 19l-7-7 7-7"
              />
            </svg>
          </button>

          {/* Close Button - Bigger X */}
          <button
            onClick={() => navigate("/profile")}
            className="flex items-center justify-center w-14 h-14 bg-red-600 text-white rounded-full shadow-lg active:scale-95 transition-transform text-3xl font-bold leading-none"
          >
            ×
          </button>
        </div>
      </div>
    </div>
  );
}

function App() {
  const [isAuthenticated, setIsAuthenticated] = useState(false);
  const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
  const [showMigration, setShowMigration] = useState(false);
  const [migrating, setMigrating] = useState(false);
  const [migrationResult, setMigrationResult] = useState(null);
  const [backendOnline, setBackendOnline] = useState(null);
  const [initialRoute, setInitialRoute] = useState("/");
  const [isSyncing, setIsSyncing] = useState(false);

  // Check authentication on mount
  useEffect(() => {
    try {
      const auth = sessionStorage.getItem("authenticated");
      const authTime = sessionStorage.getItem("authTime");
      const sessionId = sessionStorage.getItem("sessionId");

      if (auth === "true" && authTime) {
        // Check if session is still valid (24 hours)
        const elapsed = Date.now() - parseInt(authTime);
        const twentyFourHours = 24 * 60 * 60 * 1000;

        if (elapsed < twentyFourHours) {
          setIsAuthenticated(true);
        } else {
          // Session expired
          sessionStorage.removeItem("authenticated");
          sessionStorage.removeItem("authTime");
          sessionStorage.removeItem("sessionId");
          sessionStorage.removeItem("username");
          sessionStorage.removeItem("role");
          sessionStorage.removeItem("permissions");
        }
      }
    } catch (err) {
      // Clear potentially corrupted session data
      sessionStorage.removeItem("authenticated");
      sessionStorage.removeItem("authTime");
      sessionStorage.removeItem("sessionId");
      sessionStorage.removeItem("username");
      sessionStorage.removeItem("role");
      sessionStorage.removeItem("permissions");
    }
  }, []);

  const handleLogin = () => {
    setIsAuthenticated(true);

    // Always route to home page after login for all users
    setInitialRoute("/");
  };

  const handleLogout = () => {
    try {
      const sessionId = sessionStorage.getItem("sessionId");

      sessionStorage.removeItem("authenticated");
      sessionStorage.removeItem("authTime");
      sessionStorage.removeItem("sessionId");
      sessionStorage.removeItem("username");
      sessionStorage.removeItem("role");
      sessionStorage.removeItem("permissions");
      setIsAuthenticated(false);
      setInitialRoute("/");
    } catch (err) {
      // Force logout even if error occurs
      setIsAuthenticated(false);
      setInitialRoute("/");
    }
  };

  // Check if migration is needed on mount
  useEffect(() => {
    if (!isAuthenticated) return; // Skip if not logged in

    const apiSettings = localStorage.getItem("api_settings");
    let useLocalStorage = true;

    if (apiSettings) {
      try {
        const parsed = JSON.parse(apiSettings);
        useLocalStorage = parsed.useLocalStorage !== false;
      } catch (e) {}
    }

    // Show migration prompt if switching from localStorage to backend
    if (!useLocalStorage) {
      const hasMigrated = localStorage.getItem("data_migrated");
      if (!hasMigrated) {
        const hasLocalData =
          localStorage.getItem("SONGS") ||
          localStorage.getItem("PROFILES") ||
          localStorage.getItem("PLANS");
        if (hasLocalData) {
          setShowMigration(true);
        }
      }
    }
  }, [isAuthenticated]);

  // Backend status heartbeat in Online Mode
  useEffect(() => {
    if (!isAuthenticated) return; // Skip if not logged in

    let timer;
    async function check() {
      try {
        const apiSettings = localStorage.getItem("api_settings");
        const parsed = apiSettings
          ? JSON.parse(apiSettings)
          : { useLocalStorage: true };
        if (parsed.useLocalStorage) {
          setBackendOnline(null);
          return;
        }
        const { pingBackend } = await import("./api");
        const res = await pingBackend(2000);
        setBackendOnline(res.online);
      } catch (e) {
        setBackendOnline(false);
      }
    }
    check();
    timer = setInterval(check, 10000);
    return () => clearInterval(timer);
  }, [isAuthenticated]);

  // Cross-device sync polling (since WebSocket isn't implemented)
  useEffect(() => {
    if (!isAuthenticated) return; // Skip if not logged in

    let syncTimer;
    async function pollForChanges() {
      try {
        const apiSettings = localStorage.getItem("api_settings");
        const parsed = apiSettings
          ? JSON.parse(apiSettings)
          : { useLocalStorage: true };
        if (parsed.useLocalStorage) return; // Skip if in local mode

        // Trigger refresh events to reload data across all components
        window.dispatchEvent(new Event("songsChanged"));
        window.dispatchEvent(new Event("plansChanged"));
        window.dispatchEvent(new Event("profileChanged"));
      } catch (e) {}
    }
    // Poll every 5 seconds when in online mode
    syncTimer = setInterval(pollForChanges, 5000);
    return () => clearInterval(syncTimer);
  }, [isAuthenticated]);

  // Auto-close mobile menu on scroll with debounce to prevent glitches
  useEffect(() => {
    if (!mobileMenuOpen) return;

    let scrollTimeout;
    const handleScroll = () => {
      // Debounce to prevent excessive re-renders
      clearTimeout(scrollTimeout);
      scrollTimeout = setTimeout(() => {
        setMobileMenuOpen(false);
      }, 100);
    };

    // Use only window scroll listener to avoid duplicates
    window.addEventListener("scroll", handleScroll, { passive: true });

    return () => {
      clearTimeout(scrollTimeout);
      window.removeEventListener("scroll", handleScroll);
    };
  }, [mobileMenuOpen]);

  async function handleSync() {
    if (isSyncing) return;

    setIsSyncing(true);

    try {
      // Check if in local mode
      const apiSettings = localStorage.getItem("api_settings");
      const parsed = apiSettings
        ? JSON.parse(apiSettings)
        : { useLocalStorage: true };

      if (parsed.useLocalStorage) {
        alert(
          "⚠️ Sync is only available in Online Mode.\n\nPlease go to Settings and switch to Online Mode to enable server synchronization."
        );
        setIsSyncing(false);
        return;
      }

      console.log("[Sync] Starting full bidirectional sync...");
      console.log("[Sync] API Settings:", parsed);

      // Build API URL for testing
      const portPart = parsed.port ? `:${parsed.port}` : "";
      const apiUrl = `${parsed.protocol}://${parsed.hostname}${portPart}/api`;
      console.log("[Sync] API URL:", apiUrl);

      // Test backend connectivity first
      try {
        console.log("[Sync] Testing backend connectivity...");
        const healthCheck = await fetch(`${apiUrl}/health`, {
          method: "GET",
          signal: AbortSignal.timeout(5000),
        });
        console.log("[Sync] Backend health check status:", healthCheck.status);

        if (!healthCheck.ok) {
          throw new Error(
            `Backend not responding (HTTP ${healthCheck.status}). Please check:\n` +
              `• Backend server is running on port ${parsed.port || "8080"}\n` +
              `• DNS hostname ${parsed.hostname} is accessible\n` +
              `• Firewall allows port ${parsed.port || "8080"}`
          );
        }
      } catch (healthError) {
        console.error("[Sync] Backend health check failed:", healthError);
        throw new Error(
          `Cannot reach backend server at ${apiUrl}\n\n` +
            `Error: ${healthError.message}\n\n` +
            `Please verify:\n` +
            `• Internet connection is active\n` +
            `• DNS hostname is correct in Settings\n` +
            `• Backend server is running\n` +
            `• Port forwarding is configured`
        );
      }

      // Perform full bidirectional sync
      const { fullSync } = await import("./migration");
      const result = await fullSync();

      console.log("[Sync] Result:", result);

      if (result.success) {
        // Show success notification
        const notification = document.createElement("div");
        notification.innerHTML = `
          <div style="font-weight:600;margin-bottom:4px;">✅ Sync Complete!</div>
          <div style="font-size:0.85rem;opacity:0.9;">
            Uploaded: ${result.upload?.migrated?.songs || 0} songs, 
            ${result.upload?.migrated?.profiles || 0} profiles
            <br>
            Downloaded: ${result.download?.synced?.songs?.added || 0} new songs
          </div>
        `;
        notification.style.cssText =
          "position:fixed;top:90px;right:20px;background:#10b981;color:white;padding:16px 20px;border-radius:12px;z-index:9999;box-shadow:0 8px 16px rgba(0,0,0,0.2);animation:slideInRight 0.3s ease;max-width:320px;";
        document.body.appendChild(notification);
        setTimeout(() => notification.remove(), 5000);

        // Trigger data refresh
        window.dispatchEvent(new Event("songsChanged"));
        window.dispatchEvent(new Event("plansChanged"));
        window.dispatchEvent(new Event("profileChanged"));

        console.log("[Sync] Data refreshed successfully");
      } else {
        const errorMsg =
          result.upload?.error ||
          result.download?.error ||
          "Unknown sync error";
        console.error("[Sync] Sync failed:", errorMsg);
        throw new Error(errorMsg);
      }
    } catch (error) {
      console.error("[Sync] Error:", error);
      alert(`❌ Sync Failed\n\n${error.message}`);
    } finally {
      setIsSyncing(false);
    }
  }

  async function handleMigration() {
    setMigrating(true);
    try {
      const { migrateLocalStorageToBackend } = await import("./migration");
      const result = await migrateLocalStorageToBackend();
      setMigrationResult(result);
      if (result.success) {
        localStorage.setItem("data_migrated", "true");
        setTimeout(() => {
          setShowMigration(false);
          window.location.reload();
        }, 2000);
      }
    } catch (err) {
      setMigrationResult({ success: false, error: err.message });
    } finally {
      setMigrating(false);
    }
  }

  // Show login page if not authenticated (after all hooks)
  if (!isAuthenticated) {
    return <LoginPage onLogin={handleLogin} />;
  }

  return (
    <BrowserRouter
      future={{
        v7_startTransition: true,
        v7_relativeSplatPath: true,
      }}
    >
      <div
        style={{
          fontFamily:
            "-apple-system, BlinkMacSystemFont, 'Inter', 'Segoe UI', 'Roboto', sans-serif",
          minHeight: "100vh",
          background: "#f8f9fa",
        }}
      >
        {/* Modern Responsive Header */}
        <header
          style={{
            position: "fixed",
            top: 0,
            left: 0,
            right: 0,
            zIndex: 9998,
            display: "flex",
            justifyContent: "space-between",
            alignItems: "center",
            padding: "1rem 1.5rem",
            background: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
            color: "white",
            boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
            gap: "1rem",
            height: "80px",
          }}
        >
          {/* Responsive Navigation Styles */}
          <style>{`
            /* Show hamburger on mobile and tablet, hide desktop nav */
            @media screen and (max-width: 1023px) {
              .desktop-nav { display: none !important; }
              .desktop-actions { display: none !important; }
            }
            
            /* Show desktop nav, hide hamburger on desktop */
            @media screen and (min-width: 1024px) {
              .mobile-hamburger { display: none !important; }
            }
          `}</style>

          {/* Logo - Left */}
          <Link
            to="/"
            className="nav-logo-link"
            style={{
              fontWeight: "700",
              fontSize: "clamp(1.1rem, 4vw, 1.5rem)",
              display: "flex",
              alignItems: "center",
              gap: "0.5rem",
              flex: "0 0 auto",
              textDecoration: "none",
              color: "white",
              cursor: "pointer",
            }}
          >
            <img
              src="/church-logo.png"
              alt="Church Logo"
              className="nav-logo-img"
              style={{
                height: "clamp(32px, 5vw, 48px)",
                width: "auto",
                objectFit: "contain",
                filter: "brightness(0) invert(1)",
              }}
            />
            <span className="hidden sm:inline">House of Prayer</span>
            <span className="sm:hidden">HOP</span>
          </Link>

          {/* Center Navigation - Desktop Only (1024px+) */}
          <nav
            className="desktop-nav"
            style={{
              display: "flex",
              gap: "0.5rem",
              alignItems: "center",
              justifyContent: "center",
              flex: "0 1 auto",
            }}
          >
            <Link
              to="/"
              className="nav-link"
              onClick={() => {
                localStorage.removeItem("selected_profile_id");
                clearProfileSelection();
              }}
              style={{
                textDecoration: "none",
                color: "white",
                fontWeight: 600,
                padding: "0.6rem 0.9rem",
                borderRadius: "0.5rem",
                whiteSpace: "nowrap",
                fontSize: "0.9rem",
              }}
            >
              🏠 Home
            </Link>
            <Link
              to="/profile"
              className="nav-link"
              onClick={(e) => {
                localStorage.removeItem("selected_profile_id");
                clearProfileSelection();
                // If already on profile route (e.g., /profile?id=123), force navigation
                if (window.location.pathname === "/profile") {
                  e.preventDefault();
                  window.location.href = "/profile";
                }
              }}
              style={{
                textDecoration: "none",
                color: "white",
                fontWeight: 600,
                padding: "0.6rem 0.9rem",
                borderRadius: "0.5rem",
                whiteSpace: "nowrap",
                fontSize: "0.9rem",
              }}
            >
              👤 Profile
            </Link>
            <Link
              to="/database"
              className="nav-link"
              onClick={() => {
                localStorage.removeItem("selected_profile_id");
                clearProfileSelection();
              }}
              style={{
                textDecoration: "none",
                color: "white",
                fontWeight: 600,
                padding: "0.6rem 0.9rem",
                borderRadius: "0.5rem",
                whiteSpace: "nowrap",
                fontSize: "0.9rem",
              }}
            >
              📚 Database
            </Link>
            <Link
              to="/worship-list"
              className="nav-link"
              onClick={() => {
                localStorage.removeItem("selected_profile_id");
                clearProfileSelection();
              }}
              style={{
                textDecoration: "none",
                color: "white",
                fontWeight: 600,
                padding: "0.6rem 0.9rem",
                borderRadius: "0.5rem",
                whiteSpace: "nowrap",
                fontSize: "0.9rem",
              }}
            >
              🙏 Worship List
            </Link>
            <Link
              to="/settings"
              className="nav-link"
              style={{
                textDecoration: "none",
                color: "white",
                fontWeight: 600,
                padding: "0.6rem 0.9rem",
                borderRadius: "0.5rem",
                whiteSpace: "nowrap",
                fontSize: "0.9rem",
              }}
            >
              ⚙️ Settings
            </Link>
            <Link
              to="/admin"
              className="nav-link"
              style={{
                textDecoration: "none",
                color: "white",
                fontWeight: 600,
                padding: "0.6rem 0.9rem",
                borderRadius: "0.5rem",
                whiteSpace: "nowrap",
                fontSize: "0.875rem",
              }}
            >
              👑 Admin
            </Link>
            <button
              onClick={handleLogout}
              className="nav-link"
              style={{
                textDecoration: "none",
                color: "white",
                fontWeight: 600,
                padding: "0.5rem 0.75rem",
                borderRadius: "0.5rem",
                whiteSpace: "nowrap",
                border: "none",
                background: "transparent",
                cursor: "pointer",
                fontSize: "0.875rem",
              }}
            >
              🚪 Logout
            </button>
          </nav>

          {/* Right Side - Status, Actions, and Hamburger */}
          <div
            style={{
              display: "flex",
              alignItems: "center",
              gap: "0.5rem",
              flex: "0 0 auto",
            }}
          >
            {/* Backend status badge - Always visible */}
            <div className="flex items-center" style={{ flexShrink: 0 }}>
              {backendOnline === null ? (
                <span
                  style={{
                    padding: "0.25rem 0.5rem",
                    borderRadius: "0.5rem",
                    background: "rgba(233, 236, 239, 0.95)",
                    color: "#495057",
                    fontSize: "0.65rem",
                    fontWeight: 700,
                    whiteSpace: "nowrap",
                    boxShadow: "0 2px 4px rgba(0,0,0,0.1)",
                  }}
                >
                  <span className="hidden sm:inline">📴 Offline</span>
                  <span className="sm:hidden">📴</span>
                </span>
              ) : backendOnline ? (
                <span
                  style={{
                    padding: "0.25rem 0.5rem",
                    borderRadius: "0.5rem",
                    background: "rgba(209, 250, 229, 0.95)",
                    color: "#065f46",
                    fontSize: "0.65rem",
                    fontWeight: 700,
                    whiteSpace: "nowrap",
                    boxShadow: "0 2px 4px rgba(0,0,0,0.1)",
                  }}
                >
                  <span className="hidden sm:inline">🟢 Online</span>
                  <span className="sm:hidden">🟢</span>
                </span>
              ) : (
                <span
                  style={{
                    padding: "0.25rem 0.5rem",
                    borderRadius: "0.5rem",
                    background: "rgba(254, 226, 226, 0.95)",
                    color: "#991b1b",
                    fontSize: "0.65rem",
                    fontWeight: 700,
                    whiteSpace: "nowrap",
                    boxShadow: "0 2px 4px rgba(0,0,0,0.1)",
                  }}
                >
                  <span className="hidden sm:inline">🔴 Offline</span>
                  <span className="sm:hidden">🔴</span>
                </span>
              )}
            </div>

            {/* Desktop Actions - Only on Desktop (1024px+) */}
            <div
              className="desktop-actions"
              style={{
                display: "flex",
                flexShrink: 0,
                alignItems: "center",
                gap: "0.5rem",
              }}
            >
              <ProfileDropdown />
              <ExportDropdown />
              <button
                onClick={handleSync}
                disabled={isSyncing}
                aria-label="Synchronize data with server"
                title="Sync local changes with server database"
                type="button"
                className="nav-sync-btn"
                style={{
                  padding: "0.5rem 0.75rem",
                  background: isSyncing
                    ? "rgba(255,255,255,0.1)"
                    : "rgba(255,255,255,0.2)",
                  border: "2px solid rgba(255,255,255,0.2)",
                  borderRadius: "0.75rem",
                  color: "white",
                  cursor: isSyncing ? "not-allowed" : "pointer",
                  fontWeight: 600,
                  fontSize: "0.8rem",
                  whiteSpace: "nowrap",
                  opacity: isSyncing ? 0.6 : 1,
                }}
              >
                {isSyncing ? "🔄 Syncing..." : "🔄 Sync"}
              </button>
            </div>

            {/* Mobile/Tablet Hamburger - Outside desktop-actions (< 1024px) */}
            <button
              onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
              className="mobile-hamburger"
              aria-label={mobileMenuOpen ? "Close menu" : "Open menu"}
              aria-expanded={mobileMenuOpen}
              type="button"
              style={{
                padding: "0.75rem",
                background: mobileMenuOpen
                  ? "rgba(255,255,255,0.3)"
                  : "rgba(255,255,255,0.2)",
                border: "2px solid rgba(255,255,255,0.4)",
                borderRadius: "0.75rem",
                color: "white",
                cursor: "pointer",
                fontSize: "1.25rem",
                fontWeight: "bold",
                transition: "background 0.2s ease",
                boxShadow: "0 2px 8px rgba(0,0,0,0.15)",
                minWidth: "44px",
                minHeight: "44px",
                display: "flex",
                alignItems: "center",
                justifyContent: "center",
                WebkitTapHighlightColor: "transparent",
                touchAction: "manipulation",
              }}
            >
              {mobileMenuOpen ? "✕" : "☰"}
            </button>
          </div>
        </header>

        {/* Mobile Menu Dropdown - Only for Phones */}
        {mobileMenuOpen && (
          <>
            {/* Backdrop - clicking closes menu */}
            <div
              onClick={() => setMobileMenuOpen(false)}
              role="button"
              aria-label="Close menu"
              tabIndex={0}
              onKeyDown={(e) => {
                if (e.key === "Enter" || e.key === " ") {
                  e.preventDefault();
                  setMobileMenuOpen(false);
                }
              }}
              style={{
                position: "fixed",
                top: 0,
                left: 0,
                right: 0,
                bottom: 0,
                background: "rgba(0,0,0,0.5)",
                zIndex: 999,
                animation: "fadeIn 0.2s ease-out",
                WebkitTapHighlightColor: "transparent",
              }}
              className="mobile-menu-backdrop"
            />

            {/* Menu Content */}
            <div
              style={{
                position: "fixed",
                top: "80px",
                left: 0,
                right: 0,
                background: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
                boxShadow: "0 4px 20px rgba(0,0,0,0.3)",
                zIndex: 9998,
                padding: "1rem",
                animation: "slideDown 0.25s ease-out",
                maxHeight: "calc(100vh - 80px)",
                overflowY: "auto",
                WebkitOverflowScrolling: "touch",
                willChange: "transform",
                transform: "translateZ(0)",
              }}
              className="mobile-menu-content"
            >
              <style>{`
                /* Tablet-specific sizing for iPad optimization */
                @media screen and (min-width: 768px) and (max-width: 1200px) {
                  header .nav-link {
                    padding: 0.4rem 0.6rem !important;
                    font-size: 0.8rem !important;
                  }
                  
                  header .nav-sync-btn {
                    font-size: 0.7rem !important;
                    padding: 0.4rem 0.6rem !important;
                  }
                  
                  header .profile-dropdown-btn,
                  header .export-dropdown-btn {
                    font-size: 0.7rem !important;
                    padding: 0.4rem 0.6rem !important;
                  }
                }
                
                /* Extra small tablets / Portrait iPad */
                @media screen and (min-width: 768px) and (max-width: 900px) {
                  header .nav-link {
                    padding: 0.35rem 0.5rem !important;
                    font-size: 0.75rem !important;
                  }
                  
                  header .nav-sync-btn {
                    font-size: 0.65rem !important;
                    padding: 0.35rem 0.5rem !important;
                  }
                  
                  header .profile-dropdown-btn,
                  header .export-dropdown-btn {
                    font-size: 0.65rem !important;
                    padding: 0.35rem 0.5rem !important;
                  }
                }
                
                @keyframes fadeIn {
                  from { opacity: 0; }
                  to { opacity: 1; }
                }
                @keyframes slideDown {
                  from { 
                    transform: translateY(-20px);
                    opacity: 0;
                  }
                  to { 
                    transform: translateY(0);
                    opacity: 1;
                  }
                }
                
                /* Navbar optimizations - GPU accelerated hover effects */
                .nav-link {
                  will-change: background;
                  transition: background 0.15s ease;
                }
                .nav-link:hover {
                  background: rgba(255,255,255,0.2) !important;
                }
                
                .nav-logo-link {
                  will-change: opacity;
                  transition: opacity 0.15s ease;
                }
                .nav-logo-link:hover {
                  opacity: 0.85 !important;
                }
                
                .nav-logo-img {
                  will-change: transform;
                  transition: transform 0.15s ease;
                }
                .nav-logo-link:hover .nav-logo-img {
                  transform: scale(1.05) !important;
                }
                
                .nav-sync-btn {
                  will-change: background, border-color;
                  transition: background 0.15s ease, border-color 0.15s ease;
                }
                .nav-sync-btn:hover {
                  background: rgba(255,255,255,0.3) !important;
                  border-color: rgba(255,255,255,0.4) !important;
                }
                
                /* Dropdown optimizations */
                .profile-dropdown-btn, .export-dropdown-btn {
                  will-change: background;
                  transition: background 0.15s ease;
                }
                .profile-dropdown-btn:hover, .export-dropdown-btn:hover {
                  background: rgba(255,255,255,0.3) !important;
                }
                
                .dropdown-item {
                  will-change: background;
                  transition: background 0.1s ease;
                  background: white;
                }
                .dropdown-item:hover {
                  background: #f5f5f5 !important;
                }
                
                .dropdown-item-selected {
                  will-change: background;
                  background: #f0f0f0;
                }
                .dropdown-item-selected:hover {
                  background: #e8e8e8 !important;
                }
                
                /* Worship cards - smooth hover animations */
                .worship-card {
                  will-change: transform, box-shadow;
                  transition: transform 0.2s ease, box-shadow 0.2s ease;
                  box-shadow: 0 4px 16px rgba(0,0,0,0.15);
                  transform: translateZ(0);
                  backface-visibility: hidden;
                }
                .worship-card:hover {
                  transform: translateY(-4px) translateZ(0);
                  box-shadow: 0 8px 24px rgba(0,0,0,0.25);
                }
                
                /* Mobile menu links */
                .mobile-menu-link {
                  background: rgba(255,255,255,0.1);
                  transition: background 0.15s ease;
                  will-change: background;
                  transform: translateZ(0);
                }
                .mobile-menu-link:active {
                  background: rgba(255,255,255,0.2) !important;
                }
                
                /* Drag state */
                .dragging {
                  opacity: 0.5;
                }
                
                /* Force GPU layer for smooth animations - only for animated elements */
                .nav-link, .nav-logo-link, .nav-sync-btn, .worship-card, .mobile-menu-link {
                  transform: translateZ(0);
                  backface-visibility: hidden;
                }
              `}</style>
              <nav
                style={{
                  display: "grid",
                  gridTemplateColumns: "repeat(2, 1fr)",
                  gap: "0.625rem",
                }}
              >
                <Link
                  to="/"
                  onClick={() => setMobileMenuOpen(false)}
                  className="mobile-menu-link"
                  style={{
                    textDecoration: "none",
                    color: "white",
                    fontWeight: 600,
                    padding: "0.75rem 0.5rem",
                    borderRadius: "0.625rem",
                    display: "flex",
                    flexDirection: "column",
                    alignItems: "center",
                    justifyContent: "center",
                    gap: "0.25rem",
                    fontSize: "0.8rem",
                    WebkitTapHighlightColor: "transparent",
                    textAlign: "center",
                    minHeight: "70px",
                    background: "rgba(255,255,255,0.15)",
                    border: "1px solid rgba(255,255,255,0.2)",
                    boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
                  }}
                >
                  <span style={{ fontSize: "1.25rem", lineHeight: 1 }}>🏠</span>
                  <span style={{ fontSize: "0.75rem" }}>Home</span>
                </Link>
                <Link
                  to="/profile"
                  onClick={(e) => {
                    setMobileMenuOpen(false);
                    localStorage.removeItem("selected_profile_id");
                    // Force navigation if already on profile route
                    if (window.location.pathname === "/profile") {
                      e.preventDefault();
                      window.location.href = "/profile";
                    }
                  }}
                  style={{
                    textDecoration: "none",
                    color: "white",
                    fontWeight: 600,
                    padding: "0.75rem 0.5rem",
                    borderRadius: "0.625rem",
                    display: "flex",
                    flexDirection: "column",
                    alignItems: "center",
                    justifyContent: "center",
                    gap: "0.25rem",
                    fontSize: "0.8rem",
                    textAlign: "center",
                    minHeight: "70px",
                    background: "rgba(255,255,255,0.15)",
                    border: "1px solid rgba(255,255,255,0.2)",
                    boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
                  }}
                >
                  <span style={{ fontSize: "1.25rem", lineHeight: 1 }}>👤</span>
                  <span style={{ fontSize: "0.75rem" }}>Profile</span>
                </Link>
                <Link
                  to="/database"
                  onClick={() => setMobileMenuOpen(false)}
                  style={{
                    textDecoration: "none",
                    color: "white",
                    fontWeight: 600,
                    padding: "0.75rem 0.5rem",
                    borderRadius: "0.625rem",
                    display: "flex",
                    flexDirection: "column",
                    alignItems: "center",
                    justifyContent: "center",
                    gap: "0.25rem",
                    fontSize: "0.8rem",
                    textAlign: "center",
                    minHeight: "70px",
                    background: "rgba(255,255,255,0.15)",
                    border: "1px solid rgba(255,255,255,0.2)",
                    boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
                  }}
                >
                  <span style={{ fontSize: "1.25rem", lineHeight: 1 }}>🎵</span>
                  <span style={{ fontSize: "0.75rem" }}>Database</span>
                </Link>
                <Link
                  to="/worship-list"
                  onClick={() => setMobileMenuOpen(false)}
                  style={{
                    textDecoration: "none",
                    color: "white",
                    fontWeight: 600,
                    padding: "0.75rem 0.5rem",
                    borderRadius: "0.625rem",
                    display: "flex",
                    flexDirection: "column",
                    alignItems: "center",
                    justifyContent: "center",
                    gap: "0.25rem",
                    fontSize: "0.8rem",
                    textAlign: "center",
                    minHeight: "70px",
                    background: "rgba(255,255,255,0.15)",
                    border: "1px solid rgba(255,255,255,0.2)",
                    boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
                  }}
                >
                  <span style={{ fontSize: "1.25rem", lineHeight: 1 }}>🙏</span>
                  <span style={{ fontSize: "0.75rem" }}>Worship</span>
                </Link>
                <Link
                  to="/settings"
                  onClick={() => setMobileMenuOpen(false)}
                  style={{
                    textDecoration: "none",
                    color: "white",
                    fontWeight: 600,
                    padding: "0.75rem 0.5rem",
                    borderRadius: "0.625rem",
                    display: "flex",
                    flexDirection: "column",
                    alignItems: "center",
                    justifyContent: "center",
                    gap: "0.25rem",
                    fontSize: "0.8rem",
                    textAlign: "center",
                    minHeight: "70px",
                    background: "rgba(255,255,255,0.15)",
                    border: "1px solid rgba(255,255,255,0.2)",
                    boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
                  }}
                >
                  <span style={{ fontSize: "1.25rem", lineHeight: 1 }}>⚙️</span>
                  <span style={{ fontSize: "0.75rem" }}>Settings</span>
                </Link>
                <Link
                  to="/admin"
                  onClick={() => setMobileMenuOpen(false)}
                  style={{
                    textDecoration: "none",
                    color: "white",
                    fontWeight: 600,
                    padding: "0.75rem 0.5rem",
                    borderRadius: "0.625rem",
                    display: "flex",
                    flexDirection: "column",
                    alignItems: "center",
                    justifyContent: "center",
                    gap: "0.25rem",
                    fontSize: "0.8rem",
                    textAlign: "center",
                    minHeight: "70px",
                    background: "rgba(255,255,255,0.15)",
                    border: "1px solid rgba(255,255,255,0.2)",
                    boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
                  }}
                >
                  <span style={{ fontSize: "1.25rem", lineHeight: 1 }}>👑</span>
                  <span style={{ fontSize: "0.75rem" }}>Admin</span>
                </Link>

                {/* Additional action buttons in same grid */}
                <button
                  onClick={async () => {
                    try {
                      const plans = await fetchPlans();
                      if (plans && plans.length > 0) {
                        window.open(exportPlanURL(plans[0].id), "_blank");
                      }
                      setMobileMenuOpen(false);
                    } catch (e) {}
                  }}
                  style={{
                    textDecoration: "none",
                    color: "white",
                    fontWeight: 600,
                    padding: "0.75rem 0.5rem",
                    borderRadius: "0.625rem",
                    display: "flex",
                    flexDirection: "column",
                    alignItems: "center",
                    justifyContent: "center",
                    gap: "0.25rem",
                    fontSize: "0.8rem",
                    textAlign: "center",
                    minHeight: "70px",
                    background: "rgba(255,255,255,0.15)",
                    border: "1px solid rgba(255,255,255,0.2)",
                    boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
                    cursor: "pointer",
                  }}
                >
                  <span style={{ fontSize: "1.25rem", lineHeight: 1 }}>📄</span>
                  <span style={{ fontSize: "0.75rem" }}>Export</span>
                </button>

                <button
                  onClick={async () => {
                    setMobileMenuOpen(false);
                    await handleSync();
                  }}
                  disabled={isSyncing}
                  style={{
                    textDecoration: "none",
                    color: "white",
                    fontWeight: 600,
                    padding: "0.75rem 0.5rem",
                    borderRadius: "0.625rem",
                    display: "flex",
                    flexDirection: "column",
                    alignItems: "center",
                    justifyContent: "center",
                    gap: "0.25rem",
                    fontSize: "0.8rem",
                    textAlign: "center",
                    minHeight: "70px",
                    background: isSyncing
                      ? "rgba(255,255,255,0.08)"
                      : "rgba(255,255,255,0.15)",
                    border: "1px solid rgba(255,255,255,0.2)",
                    boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
                    cursor: isSyncing ? "not-allowed" : "pointer",
                    opacity: isSyncing ? 0.5 : 1,
                  }}
                >
                  <span style={{ fontSize: "1.25rem", lineHeight: 1 }}>🔄</span>
                  <span style={{ fontSize: "0.75rem" }}>
                    {isSyncing ? "Syncing..." : "Sync"}
                  </span>
                </button>

                <button
                  onClick={() => {
                    handleLogout();
                    setMobileMenuOpen(false);
                  }}
                  style={{
                    textDecoration: "none",
                    color: "white",
                    fontWeight: 600,
                    padding: "0.75rem 0.5rem",
                    borderRadius: "0.625rem",
                    display: "flex",
                    flexDirection: "column",
                    alignItems: "center",
                    justifyContent: "center",
                    gap: "0.25rem",
                    fontSize: "0.8rem",
                    textAlign: "center",
                    minHeight: "70px",
                    background: "rgba(220, 38, 38, 0.85)",
                    border: "1px solid rgba(220, 38, 38, 0.5)",
                    boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
                    cursor: "pointer",
                    gridColumn: "span 2",
                  }}
                >
                  <span style={{ fontSize: "1.25rem", lineHeight: 1 }}>🚪</span>
                  <span style={{ fontSize: "0.75rem" }}>Logout</span>
                </button>
              </nav>
            </div>
          </>
        )}

        {/* Migration Modal */}
        {showMigration && (
          <div
            style={{
              position: "fixed",
              inset: 0,
              background: "rgba(0,0,0,0.8)",
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
              zIndex: 9999,
              padding: "20px",
            }}
          >
            <div
              style={{
                background: "white",
                borderRadius: 20,
                padding: 40,
                maxWidth: 600,
                boxShadow: "0 20px 60px rgba(0,0,0,0.4)",
              }}
            >
              <h2
                style={{
                  fontSize: 28,
                  fontWeight: "bold",
                  marginBottom: 20,
                  color: "#1a1a1a",
                }}
              >
                🔄 Migrate Local Data to Backend
              </h2>

              {!migrationResult ? (
                <>
                  <p
                    style={{ marginBottom: 20, fontSize: 16, lineHeight: 1.6 }}
                  >
                    You have existing songs and profiles stored locally. Would
                    you like to migrate them to the backend server for
                    multi-device sync?
                  </p>
                  <p style={{ marginBottom: 24, fontSize: 14, color: "#666" }}>
                    This will copy all your songs, profiles, plans, and settings
                    to the backend without deleting the local copies.
                  </p>
                  <div style={{ display: "flex", gap: 12 }}>
                    <button
                      onClick={handleMigration}
                      disabled={migrating}
                      style={{
                        flex: 1,
                        padding: "14px 24px",
                        background: migrating ? "#ccc" : "#667eea",
                        color: "white",
                        border: "none",
                        borderRadius: 12,
                        fontSize: 16,
                        fontWeight: "bold",
                        cursor: migrating ? "not-allowed" : "pointer",
                      }}
                    >
                      {migrating ? "⏳ Migrating..." : "✅ Yes, Migrate Now"}
                    </button>
                    <button
                      onClick={() => {
                        localStorage.setItem("data_migrated", "skip");
                        setShowMigration(false);
                      }}
                      disabled={migrating}
                      style={{
                        flex: 1,
                        padding: "14px 24px",
                        background: "#e0e0e0",
                        color: "#333",
                        border: "none",
                        borderRadius: 12,
                        fontSize: 16,
                        fontWeight: "bold",
                        cursor: migrating ? "not-allowed" : "pointer",
                      }}
                    >
                      Skip for Now
                    </button>
                  </div>
                </>
              ) : (
                <div>
                  {migrationResult.success ? (
                    <>
                      <div
                        style={{
                          padding: 20,
                          background: "#d4edda",
                          borderRadius: 12,
                          marginBottom: 20,
                          color: "#155724",
                        }}
                      >
                        <h3 style={{ fontSize: 20, marginBottom: 12 }}>
                          ✅ Migration Successful!
                        </h3>
                        <ul style={{ marginLeft: 20, lineHeight: 2 }}>
                          <li>Songs: {migrationResult.migrated.songs}</li>
                          <li>Profiles: {migrationResult.migrated.profiles}</li>
                          <li>Plans: {migrationResult.migrated.plans}</li>
                          <li>
                            Profile Songs:{" "}
                            {migrationResult.migrated.profileSongs}
                          </li>
                          <li>Song Keys: {migrationResult.migrated.keys}</li>
                        </ul>
                      </div>
                      <p style={{ fontSize: 14, color: "#666" }}>
                        Page will reload automatically...
                      </p>
                    </>
                  ) : (
                    <>
                      <div
                        style={{
                          padding: 20,
                          background: "#f8d7da",
                          borderRadius: 12,
                          marginBottom: 20,
                          color: "#721c24",
                        }}
                      >
                        <h3 style={{ fontSize: 20, marginBottom: 12 }}>
                          ❌ Migration Failed
                        </h3>
                        <p>{migrationResult.error}</p>
                      </div>
                      <button
                        onClick={() => setShowMigration(false)}
                        style={{
                          width: "100%",
                          padding: "12px",
                          background: "#667eea",
                          color: "white",
                          border: "none",
                          borderRadius: 12,
                          fontSize: 16,
                          fontWeight: "bold",
                          cursor: "pointer",
                        }}
                      >
                        Close
                      </button>
                    </>
                  )}
                </div>
              )}
            </div>
          </div>
        )}

        {/* Main Content - Add padding-top to account for fixed header */}
        <div style={{ paddingTop: "80px" }}>
          <Routes>
            <Route path="/" element={<Home />} />
            <Route path="/profile" element={<Profile />} />
            <Route path="/database" element={<Database />} />
            <Route path="/worship-list" element={<Planning />} />
            <Route path="/settings" element={<Settings />} />
            <Route path="/planning" element={<Planning />} />
            <Route path="/admin" element={<AdminPage />} />
            {/* Mobile-specific full-page views */}
            <Route
              path="/view-worship-plan"
              element={<MobileWorshipPlanView />}
            />
            <Route
              path="/view-worship-song"
              element={<MobileWorshipSongView />}
            />
            <Route
              path="/view-database-song"
              element={<MobileDatabaseSongView />}
            />
            <Route
              path="/view-profile-song"
              element={<MobileProfileSongView />}
            />
          </Routes>
        </div>
      </div>
    </BrowserRouter>
  );
}

export default App;
