"use client";

import { useState, useEffect, useCallback, useRef } from "react";
import { useAuth } from "@/lib/AuthContext";
import { useRouter } from "next/navigation";
import ErrorFeedback from "@/components/ErrorFeedback";
import {
  Compass, MapPin, Navigation, LocateFixed,
  Locate, Loader2, AlertTriangle, Info, RefreshCw,
} from "lucide-react";
import { qiblaBearing, distanceToMecca, bearingToDirection, formatDistance, KAABA_LAT, KAABA_LNG } from "@/lib/qibla";

// ── Types ──
interface GeoPosition {
  lat: number;
  lng: number;
  accuracy: number;
}

// ── Compass SVG ──
function CompassRose({ qiblaAngle, deviceHeading, size = 260 }: { qiblaAngle: number; deviceHeading: number | null; size?: number }) {
  const cx = size / 2;
  const cy = size / 2;
  const outerR = size / 2 - 8;
  const innerR = size / 2 - 28;
  const arrowLen = outerR - 16;

  // The compass dial always points North up. Rotation of the dial to match
  // device heading is handled by CSS transform on the container.
  // qiblaAngle is the bearing from user to Mecca measured clockwise from True North.
  // So the Qibla arrow is drawn at qiblaAngle degrees from the top (North).

  return (
    <div className="relative select-none" style={{ width: size, height: size }}>
      {/* Rotating compass face: when deviceHeading is available, rotate opposite so North aligns */}
      <div
        className="absolute inset-0 transition-transform duration-150 ease-linear"
        style={{ transform: deviceHeading !== null ? `rotate(${-deviceHeading}deg)` : 'rotate(0deg)' }}
      >
        <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
          <defs>
            <radialGradient id="compassGlow">
              <stop offset="0%" stopColor="rgba(212,175,55,0.08)" />
              <stop offset="100%" stopColor="rgba(212,175,55,0)" />
            </radialGradient>
          </defs>

          {/* Outer ring glow */}
          <circle cx={cx} cy={cy} r={outerR + 4} fill="url(#compassGlow)" />

          {/* Outer ring */}
          <circle cx={cx} cy={cy} r={outerR} fill="none" stroke="rgba(255,255,255,0.08)" strokeWidth="1" />
          <circle cx={cx} cy={cy} r={innerR} fill="none" stroke="rgba(255,255,255,0.04)" strokeWidth="1" />

          {/* Cardinal direction lines & labels */}
          {[0, 45, 90, 135, 180, 225, 270, 315].map((deg) => {
            const rad = (deg - 90) * (Math.PI / 180);
            const x1 = cx + innerR * Math.cos(rad);
            const y1 = cy + innerR * Math.sin(rad);
            const x2 = cx + outerR * Math.cos(rad);
            const y2 = cy + outerR * Math.sin(rad);
            const isCardinal = deg % 90 === 0;
            const labels: Record<number, string> = { 0: "N", 90: "E", 180: "S", 270: "W" };
            const label = labels[deg] || "";
            const lx = cx + (outerR + 14) * Math.cos(rad);
            const ly = cy + (outerR + 14) * Math.sin(rad);

            return (
              <g key={deg}>
                <line x1={x1} y1={y1} x2={x2} y2={y2}
                  stroke={isCardinal ? "rgba(255,255,255,0.5)" : "rgba(255,255,255,0.15)"}
                  strokeWidth={isCardinal ? 1.5 : 0.5} />
                {label && (
                  <text x={lx} y={ly} textAnchor="middle" dominantBaseline="central"
                    fill={deg === 0 ? "#D4AF37" : "rgba(255,255,255,0.4)"}
                    fontSize={deg === 0 ? 13 : 10} fontWeight={deg === 0 ? "bold" : "normal"}>
                    {label}
                  </text>
                )}
              </g>
            );
          })}

          {/* Inner degree ticks (every 10°) */}
          {Array.from({ length: 36 }, (_, i) => i * 10).filter((d) => d % 45 !== 0).map((deg) => {
            const rad = (deg - 90) * (Math.PI / 180);
            const x1 = cx + (innerR + 5) * Math.cos(rad);
            const y1 = cy + (innerR + 5) * Math.sin(rad);
            const x2 = cx + innerR * Math.cos(rad);
            const y2 = cy + innerR * Math.sin(rad);
            return (
              <line key={deg} x1={x1} y1={y1} x2={x2} y2={y2}
                stroke="rgba(255,255,255,0.06)" strokeWidth="0.5" />
            );
          })}
        </svg>

        {/* Qibla arrow — drawn above the compass but rotates with it */}
        <div className="absolute inset-0 flex items-center justify-center pointer-events-none">
          <div
            className="absolute transition-transform duration-300 ease-out"
            style={{
              transform: `rotate(${qiblaAngle}deg)`,
              transformOrigin: 'center center',
            }}
          >
            {/* Arrow pointing toward Mecca */}
            <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} className="absolute inset-0">
              {/* Arrow shaft */}
              <line x1={cx} y1={cy + 12} x2={cx} y2={cy - arrowLen}
                stroke="#D4AF37" strokeWidth="3" strokeLinecap="round"
                opacity={0.9} />
              {/* Arrow head */}
              <polygon
                points={`${cx},${cy - arrowLen - 12} ${cx - 8},${cy - arrowLen + 4} ${cx + 8},${cy - arrowLen + 4}`}
                fill="#D4AF37"
              />
              {/* Glow dot at center */}
              <circle cx={cx} cy={cy} r={5} fill="#D4AF37" opacity={0.3}>
                <animate attributeName="r" values="5;8;5" dur="2s" repeatCount="indefinite" />
                <animate attributeName="opacity" values="0.3;0.1;0.3" dur="2s" repeatCount="indefinite" />
              </circle>
            </svg>
          </div>
        </div>
      </div>

      {/* Fixed Kaaba icon at center (doesn't rotate) */}
      <div className="absolute inset-0 flex items-center justify-center pointer-events-none">
        <div className="w-12 h-12 rounded-full bg-gradient-to-br from-gray-900 to-gray-800 border-2 border-[#D4AF37]/30 flex items-center justify-center shadow-lg">
          <svg width="22" height="22" viewBox="0 0 24 24" fill="none">
            <rect x="4" y="4" width="16" height="16" rx="2" fill="rgba(212,175,55,0.2)" stroke="#D4AF37" strokeWidth="1.5" />
            <line x1="12" y1="4" x2="12" y2="20" stroke="#D4AF37" strokeWidth="1" opacity={0.5} />
            <line x1="4" y1="12" x2="20" y2="12" stroke="#D4AF37" strokeWidth="1" opacity={0.5} />
          </svg>
        </div>
      </div>

      {/* Fixed North indicator chevron at top (doesn't rotate) */}
      <div className="absolute top-1 left-1/2 -translate-x-1/2 pointer-events-none">
        <svg width="16" height="16" viewBox="0 0 24 24" className="text-[#D4AF37]">
          <polygon points="12,2 6,12 18,12" fill="currentColor" />
        </svg>
      </div>
    </div>
  );
}

// ── Main Component ──
export default function QiblaPage() {
  const { user, token, loading: authLoading } = useAuth();
  const router = useRouter();

  const [position, setPosition] = useState<GeoPosition | null>(null);
  const [positionError, setPositionError] = useState<string | null>(null);
  const [geolocating, setGeolocating] = useState(true);
  const [deviceHeading, setDeviceHeading] = useState<number | null>(null);
  const [compassAvailable, setCompassAvailable] = useState(false);
  const [permissionState, setPermissionState] = useState<"prompt" | "granted" | "denied" | "unavailable">("prompt");
  const [showInfo, setShowInfo] = useState(false);
  const watchIdRef = useRef<number | null>(null);
  const orientationRef = useRef<number | null>(null);

  // ── Auth redirect ──
  useEffect(() => {
    if (!authLoading && !token) router.push("/auth");
  }, [authLoading, token, router]);

  // ── Geolocation ──
  const startGeolocation = useCallback(() => {
    if (!navigator.geolocation) {
      setPositionError("Geolocation not available on this device");
      setGeolocating(false);
      return;
    }

    setGeolocating(true);
    setPositionError(null);

    // One-shot high accuracy
    navigator.geolocation.getCurrentPosition(
      (pos) => {
        setPosition({
          lat: pos.coords.latitude,
          lng: pos.coords.longitude,
          accuracy: pos.coords.accuracy,
        });
        setGeolocating(false);
        setPositionError(null);
      },
      (err) => {
        setPositionError(
          err.code === 1 ? "Location permission denied — enable in settings"
          : err.code === 2 ? "Location unavailable — try again"
          : "Failed to get location"
        );
        setGeolocating(false);
      },
      { enableHighAccuracy: true, timeout: 10000, maximumAge: 300000 }
    );
  }, []);

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

  // ── Device Orientation (Compass) ──
  useEffect(() => {
    const checkPermission = async () => {
      // Check if DeviceOrientationEvent exists
      if (!window.DeviceOrientationEvent) {
        setCompassAvailable(false);
        setPermissionState("unavailable");
        return;
      }

      // iOS 13+ requires permission request
      if (typeof (DeviceOrientationEvent as any).requestPermission === "function") {
        // We'll request on user interaction — for now mark as prompt
        setPermissionState("prompt");
        setCompassAvailable(true);
        return;
      }

      // Non-iOS or older iOS — available without permission
      setCompassAvailable(true);
      setPermissionState("granted");
    };

    checkPermission();
  }, []);

  const requestCompassPermission = async () => {
    if (typeof (DeviceOrientationEvent as any).requestPermission === "function") {
      try {
        const result = await (DeviceOrientationEvent as any).requestPermission();
        setPermissionState(result === "granted" ? "granted" : "denied");
        if (result === "granted") {
          startCompass();
        }
      } catch {
        setPermissionState("denied");
      }
    } else {
      setPermissionState("granted");
      startCompass();
    }
  };

  const startCompass = () => {
    if (!window.DeviceOrientationEvent) return;

    const handler = (event: DeviceOrientationEvent) => {
      // alpha = compass heading (0-360, 0 = North)
      // webkitCompassHeading for iOS
      let heading: number | null = null;

      if (event.webkitCompassHeading !== undefined && event.webkitCompassHeading !== null) {
        heading = event.webkitCompassHeading;
      } else if (event.alpha !== null) {
        // alpha is heading from North when absolute is true
        heading = event.alpha;
      }

      if (heading !== null) {
        // Smooth the heading with a simple lerp
        if (orientationRef.current !== null) {
          let diff = heading - orientationRef.current;
          if (diff > 180) diff -= 360;
          if (diff < -180) diff += 360;
          orientationRef.current += diff * 0.3; // smoothing factor
        } else {
          orientationRef.current = heading;
        }
        setDeviceHeading(orientationRef.current);
        setCompassAvailable(true);
      }
    };

    window.addEventListener("deviceorientation", handler, true);

    return () => {
      window.removeEventListener("deviceorientation", handler, true);
    };
  };

  useEffect(() => {
    if (permissionState === "granted") {
      const cleanup = startCompass();
      return () => { if (cleanup) cleanup(); };
    }
  }, [permissionState]);

  // ── Computed values ──
  const bearing = position ? qiblaBearing(position.lat, position.lng) : 0;
  const distance = position ? distanceToMecca(position.lat, position.lng) : 0;
  const cardinalDir = bearingToDirection(bearing);
  const bearingStr = `${Math.round(bearing)}° ${cardinalDir}`;

  // ── Render ──
  return (
    <div className="min-h-dvh bg-[#0a0a0f] pb-24">
      {/* ── Header ── */}
      <div className="px-4 pt-6 pb-3 flex items-center justify-between">
        <div>
          <h1 className="text-xl font-bold text-white flex items-center gap-2">
            🕋 Qibla Finder
          </h1>
          <p className="text-xs text-gray-500 mt-0.5">Find direction to the Kaaba</p>
        </div>
        <div className="flex gap-2">
          <button onClick={() => setShowInfo((s) => !s)}
            className="w-10 h-10 rounded-xl bg-[#111118] border border-gray-800/60 flex items-center justify-center active:scale-95 transition"
            title="Info">
            <Info size={16} className="text-gray-400" />
          </button>
          <button onClick={startGeolocation} disabled={geolocating}
            className="w-10 h-10 rounded-xl bg-[#111118] border border-gray-800/60 flex items-center justify-center active:scale-95 transition"
            title="Refresh location">
            <RefreshCw size={16} className={`text-gray-400 ${geolocating ? "animate-spin" : ""}`} />
          </button>
        </div>
      </div>

      {/* ── Info Panel ── */}
      {showInfo && (
        <div className="mx-4 mb-4">
          <div className="bg-[#111118] border border-gray-800/60 rounded-2xl p-4">
            <h3 className="text-sm font-semibold text-white mb-2 flex items-center gap-2">
              <Info size={14} className="text-[#D4AF37]" /> How to use
            </h3>
            <ul className="text-xs text-gray-500 space-y-1.5 list-disc list-inside">
              <li>Enable <strong className="text-gray-400">Location</strong> for your current position</li>
              <li>Enable <strong className="text-gray-400">Motion/Orientation</strong> access for live compass</li>
              <li>Rotate your device until the gold arrow points to the 🕋 Kaaba icon</li>
              <li>The <strong className="text-gray-400">N</strong> marker shows True North</li>
              <li>Without compass sensor, use the bearing angle manually</li>
            </ul>
            <p className="text-xs text-gray-600 mt-2">
              <strong className="text-gray-500">Kaaba:</strong> {KAABA_LAT}°N, {KAABA_LNG}°E
            </p>
          </div>
        </div>
      )}

      {/* ── Compass Card ── */}
      <div className="mx-4 mb-5">
        <div className="relative bg-gradient-to-br from-[#111118] to-gray-900/80 border border-gray-800/60 rounded-3xl p-5 overflow-hidden">
          {/* Decorative glow */}
          <div className="absolute -top-16 -right-16 w-40 h-40 bg-amber-500/5 rounded-full blur-3xl" />
          <div className="absolute -bottom-10 -left-10 w-28 h-28 bg-[#D4AF37]/5 rounded-full blur-2xl" />

          <div className="relative flex flex-col items-center">
            {/* Compass */}
            {position && (
              <CompassRose qiblaAngle={bearing} deviceHeading={deviceHeading} size={260} />
            )}

            {/* Geolocating spinner */}
            {geolocating && !position && (
              <div className="flex flex-col items-center py-16 gap-3">
                <Locate size={32} className="text-[#D4AF37] animate-pulse" />
                <p className="text-sm text-gray-500">Getting your location...</p>
              </div>
            )}

            {/* Error state */}
            {!geolocating && positionError && !position && (
              <ErrorFeedback
                error={positionError}
                kind="location"
                onRetry={startGeolocation}
                context="Qibla geolocation"
              />
            )}

            {/* Bearing info */}
            {position && (
              <>
                <div className="mt-3 text-center">
                  <p className="text-3xl font-bold text-[#D4AF37] tracking-wider font-mono">
                    {bearingStr}
                  </p>
                  <p className="text-xs text-gray-500 mt-1">
                    from True North
                  </p>
                </div>

                {/* Distance + Location row */}
                <div className="flex items-center gap-4 mt-4 bg-gray-900/40 rounded-2xl px-5 py-3 border border-gray-800/40">
                  <div className="text-center">
                    <p className="text-lg font-bold text-white tabular-nums">{formatDistance(distance)}</p>
                    <p className="text-[10px] text-gray-600">to Kaaba</p>
                  </div>
                  <div className="w-px h-8 bg-gray-800" />
                  <div className="text-center">
                    <p className="text-sm font-semibold text-gray-300">
                      {position.lat.toFixed(4)}°, {position.lng.toFixed(4)}°
                    </p>
                    <p className="text-[10px] text-gray-600">
                      ±{Math.round(position.accuracy)}m accuracy
                    </p>
                  </div>
                  <div className="w-px h-8 bg-gray-800" />
                  <div className="text-center">
                    <MapPin size={16} className="mx-auto text-gray-500" />
                    <p className="text-[10px] text-gray-600 mt-0.5">
                      {position.lat >= 0 ? "N" : "S"}, {position.lng >= 0 ? "E" : "W"}
                    </p>
                  </div>
                </div>

                {/* Compass indicator */}
                <div className="flex items-center gap-3 mt-3">
                  <div className={`flex items-center gap-1.5 px-3 py-1.5 rounded-full text-xs ${
                    compassAvailable && permissionState === "granted"
                      ? "bg-emerald-900/20 text-emerald-400 border border-emerald-800/30"
                      : "bg-gray-800/40 text-gray-500 border border-gray-700/30"
                  }`}>
                    <Compass size={12} />
                    {compassAvailable && permissionState === "granted" ? "Live" : "No compass"}
                  </div>
                  <div className="flex items-center gap-1.5 px-3 py-1.5 rounded-full bg-gray-800/40 text-gray-500 border border-gray-700/30 text-xs">
                    <Navigation size={12} />
                    {deviceHeading !== null ? `${Math.round(deviceHeading)}°` : "—"}
                  </div>
                </div>
              </>
            )}
          </div>
        </div>
      </div>

      {/* ── Compass Permission (iOS) ── */}
      {permissionState === "prompt" && compassAvailable && (
        <div className="mx-4 mb-5">
          <div className="bg-amber-900/10 border border-amber-800/20 rounded-2xl p-4">
            <p className="text-xs text-amber-300/80 mb-3">
              Enable device orientation to see live compass direction:
            </p>
            <button onClick={requestCompassPermission}
              className="w-full py-3 bg-amber-900/30 border border-amber-700/40 text-amber-300 text-sm font-medium rounded-xl active:scale-95 transition min-h-[44px]">
              Enable Compass
            </button>
          </div>
        </div>
      )}

      {/* ── Compass unavailable notice ── */}
      {permissionState === "denied" && (
        <div className="mx-4 mb-5">
          <div className="bg-gray-900/30 border border-gray-800/60 rounded-2xl p-4 text-center">
            <Compass size={20} className="mx-auto text-gray-600 mb-2" />
            <p className="text-xs text-gray-500">
              Compass access denied. Use the bearing angle ({bearingStr}) to find Qibla direction manually.
            </p>
          </div>
        </div>
      )}

      {/* ── Loading overlay (auth) ── */}
      {authLoading && (
        <div className="flex items-center justify-center py-10">
          <Loader2 size={20} className="text-[#D4AF37] animate-spin" />
        </div>
      )}
    </div>
  );
}
