// File: monorepo/web/maplefile-frontend/src/pages/Anonymous/Login/CompleteLogin.jsx
import { useState, useEffect, useCallback, useMemo, useRef } from "react";
import { useNavigate, Link } from "react-router"; // Link still used for "Forgot password?"
import { useServices } from "../../../services/Services";
import {
  ArrowRightIcon,
  ArrowLeftIcon,
  LockClosedIcon,
  ShieldCheckIcon,
  CheckIcon,
  KeyIcon,
  UserIcon,
  ClockIcon,
  InformationCircleIcon,
} from "@heroicons/react/24/outline";

// UIX Components
import {
  Input,
  Button,
  Checkbox,
  Alert,
  Card,
  GDPRFooter,
  PageContainer,
  Navigation,
  ProgressIndicator,
  PageHeader,
} from "../../../components/UIX";
import { useUIXTheme } from "../../../components/UIX/themes/useUIXTheme";

const CompleteLogin = () => {
  const navigate = useNavigate();
  const { getThemeClasses } = useUIXTheme();

  // Refs for cleanup and unmount protection
  const isMountedRef = useRef(true);

  // Get services from the unified service system
  const services = useServices();
  const authManager = services?.authManager;
  const localStorageService = services?.localStorageService;

  const [password, setPassword] = useState("");
  const [email, setEmail] = useState("");
  const [loading, setLoading] = useState(false);
  const [generalError, setGeneralError] = useState("");
  const [fieldErrors, setFieldErrors] = useState({});
  const [challengeExpired, setChallengeExpired] = useState(false);
  const [resendingCode, setResendingCode] = useState(false);
  const [codeResent, setCodeResent] = useState(false);
  const [verificationData, setVerificationData] = useState(null);
  const [keepLoggedIn, setKeepLoggedIn] = useState(() => {
    // Initialize from saved preference, default to true (localStorage) for better UX
    if (services?.passwordStorageService) {
      const savedPreference = services.passwordStorageService.getStoragePreference();
      // If user has never set a preference, default to true (stay logged in)
      // If they have set a preference, respect it
      return savedPreference !== null ? savedPreference : true;
    }
    return true; // Default to keeping users logged in
  });

  useEffect(() => {
    isMountedRef.current = true;

    // Get email and verification data from previous steps
    let storedEmail = null;
    let storedVerificationData = null;

    // Try to get email from multiple sources
    if (authManager && typeof authManager.getCurrentUserEmail === "function") {
      try {
        storedEmail = authManager.getCurrentUserEmail();
        if (storedEmail && import.meta.env.DEV) {
          console.log(
            "[CompleteLogin] Using email from authManager:",
            storedEmail,
            typeof storedEmail,
          );
        }
      } catch (err) {
        if (import.meta.env.DEV) {
          console.warn(
            "[CompleteLogin] Could not get email from authManager:",
            err,
          );
        }
      }
    }

    if (!storedEmail && localStorageService) {
      try {
        storedEmail = localStorageService.getUserEmail();
        if (storedEmail && import.meta.env.DEV) {
          console.log(
            "[CompleteLogin] Using email from localStorageService:",
            storedEmail,
            typeof storedEmail,
          );
        }
      } catch (err) {
        if (import.meta.env.DEV) {
          console.warn(
            "[CompleteLogin] Could not get email from localStorageService:",
            err,
          );
        }
      }
    }

    if (!storedEmail) {
      storedEmail = sessionStorage.getItem("loginEmail");
      if (storedEmail && import.meta.env.DEV) {
        console.log(
          "[CompleteLogin] Using email from sessionStorage:",
          storedEmail,
          typeof storedEmail,
        );
      }
    }

    // Try to get verification data with schema validation
    try {
      const sessionData = sessionStorage.getItem("otpVerificationResult");
      if (sessionData) {
        const parsed = JSON.parse(sessionData);
        // Validate expected structure to prevent injection attacks
        if (
          parsed &&
          typeof parsed === 'object' &&
          (typeof parsed.challengeId === 'string' || typeof parsed.challenge_id === 'string')
        ) {
          storedVerificationData = parsed;
          if (import.meta.env.DEV) {
            console.log(
              "[CompleteLogin] Using verification data from sessionStorage",
            );
          }
        } else {
          // Invalid structure - clear corrupted data
          sessionStorage.removeItem("otpVerificationResult");
          if (import.meta.env.DEV) {
            console.warn("[CompleteLogin] Invalid verification data structure, cleared");
          }
        }
      }
    } catch (err) {
      // Parse error - clear corrupted data
      sessionStorage.removeItem("otpVerificationResult");
      if (import.meta.env.DEV) {
        console.warn(
          "[CompleteLogin] Could not parse verification data from sessionStorage:",
          err,
        );
      }
    }

    if (!storedVerificationData && localStorageService) {
      try {
        storedVerificationData =
          localStorageService.getLoginSessionData("verify_response");
        if (storedVerificationData && import.meta.env.DEV) {
          console.log(
            "[CompleteLogin] Using verification data from localStorageService",
          );
        }
      } catch (err) {
        if (import.meta.env.DEV) {
          console.warn(
            "[CompleteLogin] Could not get verification data from localStorageService:",
            err,
          );
        }
      }
    }

    if (storedEmail && storedVerificationData) {
      if (isMountedRef.current) {
        // Ensure email is a string and set both values together
        setEmail(String(storedEmail));
        setVerificationData(storedVerificationData);
      }
    } else {
      if (import.meta.env.DEV) {
        console.error(
          "[CompleteLogin] Missing email or verify data, redirecting to start",
          { email: storedEmail, verifyData: storedVerificationData },
        );
      }
      navigate("/login/request-ott");
    }

    return () => {
      isMountedRef.current = false;
    };
  }, [navigate, authManager, localStorageService]);

  const handleSubmit = useCallback(
    async (e) => {
      e.preventDefault();
      if (!isMountedRef.current) return;

      setLoading(true);
      setGeneralError("");
      setFieldErrors({});
      setChallengeExpired(false);

      try {
        // Validate services
        if (!authManager) {
          throw new Error(
            "Authentication service not available. Please refresh the page.",
          );
        }

        // Validate verification data exists (not user input - internal state)
        if (!verificationData || !verificationData.challengeId) {
          throw new Error(
            "Missing challenge data. Please start the login process again.",
          );
        }

        if (import.meta.env.DEV) {
          console.log(
            "[CompleteLogin] Completing login via AuthManager for:",
            email,
          );
          console.log("[CompleteLogin] Decrypting challenge data...");
        }

        let decryptedChallenge;
        try {
          decryptedChallenge = await authManager.decryptChallenge(
            password,
            verificationData,
          );
        } catch (decryptError) {
          if (import.meta.env.DEV) {
            console.error(
              "[CompleteLogin] Challenge decryption failed:",
              decryptError,
            );
          }
          throw new Error(
            "Failed to decrypt challenge data. Please check your password.",
          );
        }

        if (import.meta.env.DEV) {
          console.log("[CompleteLogin] Calling authManager.completeLogin...");
        }

        let response;
        try {
          response = await authManager.completeLogin(
            email,
            verificationData.challengeId,
            decryptedChallenge,
          );
        } catch (loginError) {
          if (import.meta.env.DEV) {
            console.error(
              "[CompleteLogin] AuthManager.completeLogin failed:",
              loginError,
            );
          }
          throw new Error("Failed to complete login: " + loginError.message);
        }

        // Validate response
        if (!response) {
          throw new Error("Login completion returned no response");
        }

        if (import.meta.env.DEV) {
          console.log("[CompleteLogin] Login completed successfully!", response);
        }

        // Set storage preference based on "Keep me logged in" checkbox
        // This must happen BEFORE storing the password
        if (services?.passwordStorageService) {
          services.passwordStorageService.setStoragePreference(keepLoggedIn);
          if (import.meta.env.DEV) {
            console.log(
              `[CompleteLogin] Storage preference set to: ${keepLoggedIn ? "localStorage" : "sessionStorage"}`,
            );
          }
        }

        // Store password in password storage service
        if (services?.passwordStorageService) {
          services.passwordStorageService.setPassword(password);
          if (import.meta.env.DEV) {
            console.log(
              "[CompleteLogin] Password stored in PasswordStorageService",
            );
          }
        } else {
          if (import.meta.env.DEV) {
            console.warn(
              "[CompleteLogin] PasswordStorageService not available, password not stored",
            );
          }
        }

        // Clear stored session data
        try {
          sessionStorage.removeItem("loginEmail");
          sessionStorage.removeItem("otpVerificationResult");

          if (
            localStorageService &&
            typeof localStorageService.clearLoginSessionData === "function"
          ) {
            localStorageService.clearLoginSessionData();
          }
        } catch (cleanupError) {
          if (import.meta.env.DEV) {
            console.warn(
              "[CompleteLogin] Could not clear session data:",
              cleanupError,
            );
          }
        }

        if (import.meta.env.DEV) {
          console.log(
            "[CompleteLogin] Login completed successfully, redirecting to dashboard",
          );
        }

        // Navigate to dashboard
        navigate("/dashboard");
      } catch (error) {
        if (!isMountedRef.current) return;

        if (import.meta.env.DEV) {
          console.error("[CompleteLogin] Login completion failed:", error);
          console.error("[CompleteLogin] Error type:", typeof error);
          console.error("[CompleteLogin] Error keys:", Object.keys(error));
          console.error("[CompleteLogin] Error.fieldErrors:", error.fieldErrors);
          console.error("[CompleteLogin] Error.message:", error.message);
        }

        // Parse RFC 9457 error response
        if (error.fieldErrors && Object.keys(error.fieldErrors).length > 0) {
          if (import.meta.env.DEV) {
            console.log("[CompleteLogin] Setting field errors:", error.fieldErrors);
          }
          setFieldErrors(error.fieldErrors);
          setGeneralError("Please fix the following issues:");
        } else if (error.message) {
          // Clean up technical error messages for better UX and security
          let userMessage = error.message;

          // Check for expired challenge FIRST (most specific)
          if (
            userMessage.includes("Invalid or expired challenge") ||
            userMessage.includes("Invalid or expired login challenge") ||
            userMessage.includes("expired challenge") ||
            userMessage.includes("request a new login code")
          ) {
            if (import.meta.env.DEV) {
              console.log(
                "[CompleteLogin] Challenge expired - automatically requesting new code",
              );
            }
            setChallengeExpired(true);
            setGeneralError("");

            // Automatically request a new OTT code
            if (authManager && email) {
              setResendingCode(true);
              try {
                await authManager.requestOTT(email);
                if (import.meta.env.DEV) {
                  console.log("[CompleteLogin] New OTT code requested successfully");
                }
                setCodeResent(true);
              } catch (resendError) {
                if (import.meta.env.DEV) {
                  console.error("[CompleteLogin] Failed to auto-resend OTT:", resendError);
                }
                // Don't set error - user can still manually request via button
                setCodeResent(false);
              } finally {
                setResendingCode(false);
              }
            }
            return;
          }

          // Sanitize technical error messages (OWASP A01: Information Disclosure)
          userMessage = userMessage.replace(/^Failed to complete login:\s*/i, "");
          userMessage = userMessage.replace(/^Failed to decrypt challenge data\.\s*/i, "");
          userMessage = userMessage.replace(/^Request failed:\s*/i, "");
          userMessage = userMessage.replace(/^Error:\s*/i, "");

          // Replace generic validation message with friendlier one
          if (userMessage.includes("One or more fields failed validation")) {
            userMessage = "Please check your password and try again.";
          }

          // Friendly message for wrong password (avoid exposing internal error details)
          if (
            userMessage.includes("Decryption failed") ||
            userMessage.includes("Challenge verification failed") ||
            userMessage.includes("wrong secret key") ||
            userMessage.includes("check your password")
          ) {
            userMessage = "Incorrect password. Please check your master password and try again.";
          }

          // Friendly message for network errors (avoid exposing server details)
          if (
            userMessage.includes("fetch") ||
            userMessage.includes("network") ||
            userMessage.includes("500") ||
            userMessage.includes("503") ||
            userMessage.includes("502")
          ) {
            userMessage = "Connection error. Please check your internet connection and try again.";
          }

          // Sanitize any remaining technical details (OWASP A01: Information Disclosure)
          if (
            userMessage.includes("undefined") ||
            userMessage.includes("null") ||
            userMessage.includes("method not found") ||
            userMessage.includes("not defined") ||
            userMessage.includes("is not a function") ||
            userMessage.includes("Available methods")
          ) {
            userMessage = "Service temporarily unavailable. Please try again later.";
          }

          setGeneralError(userMessage);
        } else {
          setGeneralError("Could not complete login. Please try again.");
        }
      } finally {
        if (isMountedRef.current) {
          setLoading(false);
        }
      }
    },
    [
      authManager,
      email,
      password,
      verificationData,
      keepLoggedIn,
      services,
      navigate,
      localStorageService,
    ],
  );

  const handleStartOver = useCallback(() => {
    // Clear all session data and error states
    setGeneralError("");
    setFieldErrors({});
    setChallengeExpired(false);

    try {
      sessionStorage.removeItem("loginEmail");
      sessionStorage.removeItem("otpVerificationResult");

      if (
        localStorageService &&
        typeof localStorageService.clearLoginSessionData === "function"
      ) {
        localStorageService.clearLoginSessionData();
      }
    } catch (cleanupError) {
      if (import.meta.env.DEV) {
        console.warn(
          "[CompleteLogin] Could not clear session data:",
          cleanupError,
        );
      }
    }

    navigate("/login/request-ott");
  }, [navigate, localStorageService]);

  const handlePasswordChange = useCallback(
    (value) => {
      setPassword(value);
      if (generalError) setGeneralError("");
      if (Object.keys(fieldErrors).length > 0) setFieldErrors({});
      if (challengeExpired) setChallengeExpired(false);
    },
    [generalError, fieldErrors, challengeExpired],
  );

  const handleKeepLoggedInChange = useCallback((checked) => {
    setKeepLoggedIn(checked);
  }, []);

  // Memoize display email
  const displayEmail = useMemo(() => email || "", [email]);

  // Memoize progress steps
  const progressSteps = useMemo(
    () => [
      { label: "Email", completed: true },
      { label: "Verify", completed: true },
      { label: "Access", completed: false },
    ],
    [],
  );

  // Memoize navigation links
  const navLinks = useMemo(
    () => [{ to: "/register", text: "Create account", variant: "secondary" }],
    [],
  );

  // Early return if verification data is not available
  if (!verificationData) {
    return (
      <PageContainer>
        <Card className="text-center p-8 max-w-md mx-auto mt-20">
          <h2 className={`text-2xl font-bold ${getThemeClasses("text-primary")} mb-4`}>
            Loading...
          </h2>
          <p className={getThemeClasses("text-secondary")}>
            Preparing secure login...
          </p>
        </Card>
      </PageContainer>
    );
  }

  return (
    <PageContainer showBlobs>
      {/* Navigation */}
      <Navigation icon={LockClosedIcon} logoText="MapleFile" links={navLinks} />

      {/* Main Content */}
      <div className="flex-1 flex items-center justify-center px-4 sm:px-6 lg:px-8 py-12 relative z-10">
        <div className="w-full max-w-md space-y-8">
          {/* Progress Indicator */}
          <ProgressIndicator steps={progressSteps} currentStep={3} />

          {/* Header */}
          <PageHeader
            icon={KeyIcon}
            title="Unlock Your Account"
            subtitle="Enter your master password to decrypt your data."
            className="text-center"
          />

          {/* GDPR Notice - Master Password Privacy */}
          <Alert type="info">
            <div className="text-xs space-y-1">
              <p className="font-semibold">
                Privacy Notice
              </p>
              <p>
                Your master password is <strong>never transmitted or stored on our servers</strong> and is used only locally in your browser to decrypt your data.
              </p>
            </div>
          </Alert>

          {/* Form Card */}
          <Card>
            {/* Challenge Expired Message */}
            {challengeExpired && (
              <Alert type={codeResent ? "success" : "warning"} className="mb-6">
                <div>
                  <h3 className="text-sm font-semibold">
                    {resendingCode
                      ? "Sending New Code..."
                      : codeResent
                        ? "New Code Sent!"
                        : "Security Code Expired"}
                  </h3>
                  <p className="text-sm mt-1 mb-3">
                    {resendingCode
                      ? "Please wait while we send a new one-time code to your email."
                      : codeResent
                        ? "A new one-time code has been sent to your email. Please check your inbox and enter the code."
                        : "Please request a new one-time code."}
                  </p>
                  <Button
                    onClick={() => navigate("/login/verify-ott", { state: { codeResent: codeResent } })}
                    variant={codeResent ? "primary" : "warning"}
                    size="sm"
                    disabled={resendingCode}
                  >
                    <span className="inline-flex items-center justify-center gap-2">
                      <ArrowLeftIcon className="h-4 w-4" />
                      <span>{codeResent ? "Enter New Code" : "Request New Code"}</span>
                    </span>
                  </Button>
                </div>
              </Alert>
            )}

            {/* Error Messages */}
            {(generalError || Object.keys(fieldErrors).length > 0) && !challengeExpired && (
              <Alert type="error" className="mb-6">
                {generalError && (
                  <p className="text-sm">{generalError}</p>
                )}
                {Object.keys(fieldErrors).length > 0 && (
                  <div className="mt-2">
                    <p className="text-sm font-semibold mb-1">
                      Please fix the following errors:
                    </p>
                    <ul className="list-disc list-inside text-sm space-y-1">
                      {Object.entries(fieldErrors).map(([field, message]) => (
                        <li key={field}>
                          <span className="font-medium capitalize">{field}:</span> {message}
                        </li>
                      ))}
                    </ul>
                  </div>
                )}
              </Alert>
            )}

            {/* User Display */}
            <div className={`mb-6 p-3 ${getThemeClasses("bg-muted")} rounded-lg border ${getThemeClasses("border-secondary")}`}>
              <div className="flex items-center">
                <UserIcon className={`h-5 w-5 ${getThemeClasses("text-muted")} mr-3`} />
                <div className="flex-1">
                  <p className={`text-xs font-medium ${getThemeClasses("text-secondary")}`}>
                    Signing in as
                  </p>
                  <p className={`text-sm ${getThemeClasses("text-primary")} font-semibold`}>{displayEmail}</p>
                </div>
                <Button
                  onClick={handleStartOver}
                  disabled={loading}
                  variant="ghost"
                  size="sm"
                  className={`${getThemeClasses("link-primary")} hover:underline px-2 py-1`}
                >
                  Change
                </Button>
              </div>
            </div>

            {/* Form */}
            <form onSubmit={handleSubmit} className="space-y-6">
              <Input
                label="Master Password"
                type="password"
                name="password"
                placeholder="Enter your master password"
                value={password}
                onChange={handlePasswordChange}
                disabled={loading || challengeExpired}
                required
                error={fieldErrors.password || fieldErrors.decryptedData}
                icon={KeyIcon}
                showPasswordToggle={true}
              />

              {/* Keep me logged in checkbox with GDPR notice */}
              <div className={`p-3 rounded-lg border transition-all duration-200 ${
                keepLoggedIn
                  ? `${getThemeClasses("alert-warning-bg")} ${getThemeClasses("alert-warning-border")}`
                  : `${getThemeClasses("bg-muted")} ${getThemeClasses("border-secondary")}`
              }`}>
                <Checkbox
                  label={
                    <span className={`font-medium ${getThemeClasses("text-primary")} flex items-center`}>
                      Keep me logged in
                      {keepLoggedIn && (
                        <span className={`ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium ${getThemeClasses("badge-warning-bg")} ${getThemeClasses("badge-warning-text")}`}>
                          Less Secure
                        </span>
                      )}
                    </span>
                  }
                  checked={keepLoggedIn}
                  onChange={handleKeepLoggedInChange}
                  disabled={loading || challengeExpired}
                />
                {keepLoggedIn ? (
                  <div className={`ml-7 mt-1.5 text-xs ${getThemeClasses("text-warning")}`}>
                    <p>
                      <span className="font-semibold">GDPR Notice:</span> Your encrypted password will be stored in localStorage to keep you logged in between sessions (only use on trusted devices).
                    </p>
                  </div>
                ) : (
                  <p className={`${getThemeClasses("text-secondary")} text-xs mt-1 ml-7`}>
                    You'll need to log in again after closing your browser. Your encrypted
                    password will be stored in sessionStorage only.
                  </p>
                )}
              </div>

              <div className="space-y-3">
                <Button
                  type="submit"
                  variant="primary"
                  fullWidth
                  disabled={loading || !authManager || challengeExpired}
                  loading={loading}
                  loadingText="Decrypting & Signing In..."
                >
                  <span className="inline-flex items-center justify-center gap-2">
                    <span>Decrypt & Access Account</span>
                    <ArrowRightIcon className="h-5 w-5" />
                  </span>
                </Button>

                {/* Forgot Password Link */}
                <div className="text-center">
                  <Link
                    to="/recovery"
                    className={`text-sm ${getThemeClasses("link-primary")} font-medium`}
                  >
                    Forgot your password?
                  </Link>
                </div>
              </div>
            </form>
          </Card>
        </div>
      </div>

      {/* Footer - GDPR Rights */}
      <GDPRFooter />
    </PageContainer>
  );
};

export default CompleteLogin;
