// src/pages/admin/components/ProfileManager.tsx
import React, { useState, useEffect } from 'react';
import type { Profile, Address, UserProfile } from '../../../types';
import { notifySuccess, notifyError } from '../../../services/notificationService';
import { logger } from '../../../services/logger.client';
import { LoadingSpinner } from '../../../components/LoadingSpinner';
import { XMarkIcon } from '../../../components/icons/XMarkIcon';
import { GoogleIcon } from '../../../components/icons/GoogleIcon';
import { GithubIcon } from '../../../components/icons/GithubIcon';
import { ConfirmationModal } from '../../../components/ConfirmationModal';
import { PasswordInput } from '../../../components/PasswordInput';
import { MapView } from '../../../components/MapView';
import type { AuthStatus } from '../../../hooks/useAuth';
import { AuthView } from './AuthView';
import { AddressForm } from './AddressForm';
import { useProfileAddress } from '../../../hooks/useProfileAddress';
import {
  useUpdateProfileMutation,
  useUpdateAddressMutation,
  useUpdatePasswordMutation,
  useUpdatePreferencesMutation,
  useExportDataMutation,
  useDeleteAccountMutation,
} from '../../../hooks/mutations/useProfileMutations';

export interface ProfileManagerProps {
  isOpen: boolean;
  onClose: () => void;
  authStatus: AuthStatus;
  userProfile: UserProfile | null; // Can be null for login/register
  onProfileUpdate: (updatedProfile: Profile) => void;
  onSignOut: () => void;
  onLoginSuccess: (user: UserProfile, token: string, rememberMe: boolean) => void; // Add login handler
}

export const ProfileManager: React.FC<ProfileManagerProps> = ({
  isOpen,
  onClose,
  authStatus,
  userProfile,
  onProfileUpdate,
  onSignOut,
  onLoginSuccess,
}) => {
  const [activeTab, setActiveTab] = useState('profile');

  // Profile state
  const [fullName, setFullName] = useState(userProfile?.full_name || '');
  const [avatarUrl, setAvatarUrl] = useState(userProfile?.avatar_url || '');

  // Address logic is now encapsulated in this custom hook.
  const { address, initialAddress, isGeocoding, handleAddressChange, handleManualGeocode } =
    useProfileAddress(userProfile, isOpen);

  // TanStack Query mutations
  const updateProfileMutation = useUpdateProfileMutation();
  const updateAddressMutation = useUpdateAddressMutation();
  const updatePasswordMutation = useUpdatePasswordMutation();
  const updatePreferencesMutation = useUpdatePreferencesMutation();
  const exportDataMutation = useExportDataMutation();
  const deleteAccountMutation = useDeleteAccountMutation();

  const profileLoading = updateProfileMutation.isPending;
  const addressLoading = updateAddressMutation.isPending;
  const passwordLoading = updatePasswordMutation.isPending;
  const exportLoading = exportDataMutation.isPending;
  const deleteLoading = deleteAccountMutation.isPending;

  // Password state
  const [password, setPassword] = useState('');
  const [confirmPassword, setConfirmPassword] = useState('');
  const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);

  const [isConfirmingDelete, setIsConfirmingDelete] = useState(false);
  const [passwordForDelete, setPasswordForDelete] = useState('');

  useEffect(() => {
    // Only reset state when the modal is opened.
    // Do not reset on profile changes, which can happen during sign-out.
    logger.debug('[useEffect] Running effect due to change in isOpen or userProfile.', {
      isOpen,
      profileExists: !!userProfile,
    });
    if (isOpen && userProfile) {
      // Ensure userProfile exists before setting state
      logger.debug('[useEffect] Modal is open with a valid profile. Resetting component state.');
      setFullName(userProfile.full_name || '');
      setAvatarUrl(userProfile.avatar_url || '');
      setActiveTab('profile');
      setIsConfirmingDelete(false);
      setPasswordForDelete('');
    }
  }, [isOpen, userProfile]); // Depend on isOpen and userProfile

  const handleProfileSave = async (e: React.FormEvent) => {
    e.preventDefault();
    logger.debug('[handleProfileSave] Save process started.');

    if (!userProfile) {
      notifyError('Cannot save profile, no user is logged in.');
      logger.warn('[handleProfileSave] Aborted: No user is logged in.');
      return;
    }

    // Determine if profile or address data has changed
    const profileDataChanged =
      fullName !== userProfile?.full_name || avatarUrl !== userProfile?.avatar_url;
    const addressDataChanged = JSON.stringify(address) !== JSON.stringify(initialAddress);

    // --- Start Debug Logging ---
    logger.debug('[handleProfileSave] Checking for data changes.', {
      profileDataChanged,
      addressDataChanged,
      currentFullName: fullName,
      initialFullName: userProfile?.full_name,
      currentAvatarUrl: avatarUrl,
      initialAvatarUrl: userProfile?.avatar_url,
      currentAddress: JSON.stringify(address),
      initialAddress: JSON.stringify(initialAddress),
    });
    // --- End Debug Logging ---

    if (!profileDataChanged && !addressDataChanged) {
      notifySuccess('No changes to save.');
      logger.debug('[handleProfileSave] No changes detected. Closing modal.');
      onClose();
      return;
    }

    // Create an array of promises for the API calls that need to be made.
    const promisesToRun: Promise<Profile | Address>[] = [];
    if (profileDataChanged) {
      logger.debug('[handleProfileSave] Queuing profile update promise.');
      promisesToRun.push(
        updateProfileMutation.mutateAsync({ full_name: fullName, avatar_url: avatarUrl }),
      );
    }
    if (addressDataChanged) {
      logger.debug('[handleProfileSave] Queuing address update promise.');
      promisesToRun.push(updateAddressMutation.mutateAsync(address));
    }

    try {
      logger.debug(`[handleProfileSave] Awaiting ${promisesToRun.length} promises...`);
      // Use Promise.allSettled to handle partial successes gracefully.
      const results = await Promise.allSettled(promisesToRun);
      logger.debug('[handleProfileSave] Promise.allSettled finished.', { results });

      let anyFailures = false;
      let successfulProfileUpdate: Profile | null = null;

      // Determine which promises succeeded or failed.
      results.forEach((result, index) => {
        const isProfilePromise = profileDataChanged && index === 0;
        if (result.status === 'rejected') {
          anyFailures = true;
        } else if (result.status === 'fulfilled' && isProfilePromise) {
          successfulProfileUpdate = result.value as Profile;
        }
      });

      // If the profile update itself was successful, notify the parent component.
      if (successfulProfileUpdate) {
        onProfileUpdate(successfulProfileUpdate);
      }

      // Only show the global success message and close the modal if everything worked.
      if (!anyFailures) {
        notifySuccess('Profile updated successfully!');
        onClose();
      } else {
        logger.warn(
          '[handleProfileSave] One or more operations failed. The mutation hook should have shown an error. The modal will remain open.',
        );
      }
    } catch (error) {
      // This catch block is a safeguard for unexpected errors.
      logger.error(
        { err: error },
        "[CRITICAL] An unexpected error was caught directly in handleProfileSave's catch block.",
      );
      notifyError(
        `An unexpected critical error occurred: ${error instanceof Error ? error.message : String(error)}`,
      );
    }

    // This log confirms the function has completed its execution.
    logger.debug('[handleProfileSave] Save process finished.');
  };

  const handleOAuthLink = async (provider: 'google' | 'github') => {
    // This will redirect the user to the OAuth provider to link the account.
    // TODO: This is a placeholder. Implement OAuth account linking via the Passport.js backend.
    if (!userProfile) {
      return; // Should not be possible to see this button if not logged in
    }

    const errorMessage = `Account linking with ${provider} is not yet implemented.`; // This was a duplicate, fixed.
    logger.warn(errorMessage, { userId: userProfile.user.user_id });
    notifyError(errorMessage);
  };

  const handlePasswordUpdate = async (e: React.FormEvent) => {
    e.preventDefault();
    if (password !== confirmPassword) {
      notifyError('Passwords do not match.');
      return;
    }
    if (password.length < 6) {
      notifyError('Password must be at least 6 characters long.');
      return;
    }

    updatePasswordMutation.mutate(
      { password },
      {
        onSuccess: () => {
          notifySuccess('Password updated successfully!');
          setPassword('');
          setConfirmPassword('');
        },
      },
    );
  };

  const handleExportData = async () => {
    exportDataMutation.mutate(undefined, {
      onSuccess: (userData) => {
        const jsonString = `data:text/json;charset=utf-8,${encodeURIComponent(JSON.stringify(userData, null, 2))}`;
        const link = document.createElement('a');
        link.href = jsonString;
        link.download = `flyer-crawler-data-export-${new Date().toISOString().split('T')[0]}.json`;
        link.click();
      },
    });
  };

  const handleDeleteAccount = async () => {
    setIsDeleteModalOpen(false); // Close the confirmation modal
    deleteAccountMutation.mutate(
      { password: passwordForDelete },
      {
        onSuccess: () => {
          notifySuccess('Account deleted successfully. You will be logged out shortly.');
          setTimeout(() => {
            onClose();
            onSignOut();
          }, 3000);
        },
      },
    );
  };

  const handleToggleDarkMode = async (newMode: boolean) => {
    updatePreferencesMutation.mutate(
      { darkMode: newMode },
      {
        onSuccess: (updatedProfile) => {
          onProfileUpdate(updatedProfile);
        },
      },
    );
  };

  const handleToggleUnitSystem = async (newSystem: 'metric' | 'imperial') => {
    updatePreferencesMutation.mutate(
      { unitSystem: newSystem },
      {
        onSuccess: (updatedProfile) => {
          onProfileUpdate(updatedProfile);
        },
      },
    );
  };

  if (!isOpen) return null;

  return (
    <div
      className="fixed inset-0 bg-black bg-opacity-60 z-50 flex justify-center items-center p-4"
      onClick={onClose}
      aria-modal="true"
      role="dialog"
    >
      <ConfirmationModal
        isOpen={isDeleteModalOpen}
        onClose={() => setIsDeleteModalOpen(false)}
        onConfirm={handleDeleteAccount} // Pass the handler directly
        title="Confirm Account Deletion"
        message={
          <>
            Are you absolutely sure you want to delete your account?
            <strong className="block mt-2">This action is permanent and cannot be undone.</strong>
          </>
        }
        confirmButtonText="Yes, Delete My Account"
      />
      <div
        className="bg-white dark:bg-gray-800 rounded-lg shadow-xl w-full max-w-lg relative"
        onClick={(e) => e.stopPropagation()}
      >
        <button
          onClick={onClose}
          className="absolute top-3 right-3 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 transition-colors"
          aria-label="Close profile manager"
        >
          <XMarkIcon className="w-6 h-6" />
        </button>

        {authStatus === 'SIGNED_OUT' ? (
          <AuthView onLoginSuccess={onLoginSuccess} onClose={onClose} />
        ) : (
          // Wrap the authenticated view in a React Fragment to return a single element
          <>
            <div className="p-8">
              <h2 className="text-2xl font-bold text-gray-800 dark:text-white mb-1">My Account</h2>
              <p className="text-sm text-gray-500 dark:text-gray-400 mb-6">
                Manage your profile, preferences, and security.
              </p>

              <div className="mb-6">
                <nav className="flex space-x-2" aria-label="Tabs">
                  <button
                    onClick={() => setActiveTab('profile')}
                    className={`whitespace-nowrap py-2 px-4 rounded-md font-medium text-sm transition-colors ${activeTab === 'profile' ? 'bg-brand-primary/10 text-brand-primary dark:bg-brand-primary/20' : 'text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-700/50 hover:text-gray-700 dark:hover:text-gray-300'}`}
                  >
                    Profile
                  </button>
                  <button
                    onClick={() => setActiveTab('security')}
                    className={`whitespace-nowrap py-2 px-4 rounded-md font-medium text-sm transition-colors ${activeTab === 'security' ? 'bg-brand-primary/10 text-brand-primary dark:bg-brand-primary/20' : 'text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-700/50 hover:text-gray-700 dark:hover:text-gray-300'}`}
                  >
                    Security
                  </button>
                  <button
                    onClick={() => setActiveTab('data')}
                    className={`whitespace-nowrap py-2 px-4 rounded-md font-medium text-sm transition-colors ${activeTab === 'data' ? 'bg-brand-primary/10 text-brand-primary dark:bg-brand-primary/20' : 'text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-700/50 hover:text-gray-700 dark:hover:text-gray-300'}`}
                  >
                    Data & Privacy
                  </button>
                  <button
                    onClick={() => setActiveTab('preferences')}
                    className={`whitespace-nowrap py-2 px-4 rounded-md font-medium text-sm transition-colors ${activeTab === 'preferences' ? 'bg-brand-primary/10 text-brand-primary dark:bg-brand-primary/20' : 'text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-700/50 hover:text-gray-700 dark:hover:text-gray-300'}`}
                  >
                    Preferences
                  </button>
                </nav>
              </div>

              {activeTab === 'profile' && (
                <form aria-label="Profile Form" onSubmit={handleProfileSave} className="space-y-4">
                  <div>
                    <label
                      htmlFor="fullName"
                      className="block text-sm font-medium text-gray-700 dark:text-gray-300"
                    >
                      Full Name
                    </label>
                    <input
                      id="fullName"
                      type="text"
                      value={fullName}
                      onChange={(e) => setFullName(e.target.value)}
                      className="mt-1 block w-full px-3 py-2 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm"
                    />
                  </div>
                  <div>
                    <label
                      htmlFor="avatarUrl"
                      className="block text-sm font-medium text-gray-700 dark:text-gray-300"
                    >
                      Avatar URL
                    </label>
                    <input
                      id="avatarUrl"
                      type="url"
                      value={avatarUrl}
                      onChange={(e) => setAvatarUrl(e.target.value)}
                      className="mt-1 block w-full px-3 py-2 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm"
                    />
                  </div>
                  <div className="border-t border-gray-200 dark:border-gray-700 pt-4">
                    <AddressForm
                      address={address}
                      onAddressChange={handleAddressChange}
                      onGeocode={handleManualGeocode}
                      isGeocoding={isGeocoding}
                    />
                  </div>
                  {address.latitude && address.longitude && (
                    <div className="pt-4" data-testid="map-view-container">
                      <MapView latitude={address.latitude} longitude={address.longitude} />
                    </div>
                  )}
                  <div className="pt-2">
                    <button
                      type="submit"
                      disabled={profileLoading || addressLoading}
                      className="w-full bg-brand-primary hover:bg-brand-dark disabled:bg-gray-400 text-white font-bold py-2.5 px-4 rounded-lg flex justify-center shadow-sm transition-colors"
                    >
                      {profileLoading || addressLoading ? (
                        <div className="w-5 h-5">
                          <LoadingSpinner />
                        </div>
                      ) : (
                        'Save Profile'
                      )}
                    </button>
                  </div>
                </form>
              )}

              {activeTab === 'security' && (
                <form
                  data-testid="update-password-form"
                  onSubmit={handlePasswordUpdate}
                  className="space-y-4"
                >
                  <div>
                    <label
                      htmlFor="newPassword"
                      className="block text-sm font-medium text-gray-700 dark:text-gray-300"
                    >
                      New Password
                    </label>
                    <PasswordInput
                      id="newPassword"
                      value={password}
                      onChange={(e) => setPassword(e.target.value)}
                      placeholder="••••••••"
                      required
                      className="mt-1"
                      showStrength
                    />
                  </div>
                  <div>
                    <label
                      htmlFor="confirmPassword"
                      className="block text-sm font-medium text-gray-700 dark:text-gray-300"
                    >
                      Confirm New Password
                    </label>
                    <PasswordInput
                      id="confirmPassword"
                      value={confirmPassword}
                      onChange={(e) => setConfirmPassword(e.target.value)}
                      placeholder="••••••••"
                      required
                      className="mt-1"
                    />
                  </div>
                  <div className="pt-2">
                    <button
                      type="submit"
                      disabled={passwordLoading}
                      className="w-full bg-brand-primary hover:bg-brand-dark disabled:bg-gray-400 text-white font-bold py-2.5 px-4 rounded-lg flex justify-center shadow-sm transition-colors"
                    >
                      {passwordLoading ? (
                        <div className="w-5 h-5">
                          <LoadingSpinner />
                        </div>
                      ) : (
                        'Update Password'
                      )}
                    </button>
                  </div>

                  <div className="border-t border-gray-200 dark:border-gray-700 pt-4">
                    <h3 className="text-md font-semibold text-gray-800 dark:text-white">
                      Link Social Accounts
                    </h3>
                    <p className="text-sm text-gray-500 dark:text-gray-400 mt-1 mb-3">
                      Connect other accounts for easier sign-in.
                    </p>
                    <div className="space-y-3">
                      <button
                        type="button"
                        onClick={() => handleOAuthLink('google')}
                        className="w-full flex items-center justify-center px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm text-sm font-medium text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700"
                      >
                        <GoogleIcon className="w-5 h-5 mr-3" />
                        Link Google Account
                      </button>
                      <button
                        type="button"
                        onClick={() => handleOAuthLink('github')}
                        className="w-full flex items-center justify-center px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm text-sm font-medium text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700"
                      >
                        <GithubIcon className="w-5 h-5 mr-3" />
                        Link GitHub Account
                      </button>
                    </div>
                  </div>
                </form>
              )}

              {activeTab === 'data' && (
                <div className="space-y-6">
                  <div>
                    <h3 className="text-md font-semibold text-gray-800 dark:text-white">
                      Export Your Data
                    </h3>
                    <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
                      Download a JSON file of your profile, watched items, and shopping lists.
                    </p>
                    <button
                      onClick={handleExportData}
                      disabled={exportLoading}
                      className="mt-3 w-full sm:w-auto bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 text-gray-800 dark:text-white font-semibold py-2 px-4 rounded-lg flex items-center justify-center border border-gray-300 dark:border-gray-600 shadow-sm transition-colors"
                    >
                      {exportLoading ? (
                        <div className="w-5 h-5">
                          <LoadingSpinner />
                        </div>
                      ) : (
                        'Export My Data'
                      )}
                    </button>
                  </div>

                  <div className="border-t border-gray-200 dark:border-gray-700"></div>

                  <div className="p-4 border border-red-500/50 dark:border-red-400/50 bg-red-50 dark:bg-red-900/20 rounded-lg">
                    <h3 className="text-md font-semibold text-red-800 dark:text-red-300">
                      Danger Zone
                    </h3>
                    <p className="text-sm text-red-700 dark:text-red-400 mt-1">
                      This action is permanent and cannot be undone. All your data will be erased.
                    </p>

                    {!isConfirmingDelete ? (
                      <button
                        type="button"
                        onClick={() => setIsConfirmingDelete(true)}
                        className="mt-3 w-full sm:w-auto bg-red-600 hover:bg-red-700 text-white font-bold py-2 px-4 rounded-lg shadow-sm transition-colors"
                      >
                        Delete My Account
                      </button>
                    ) : (
                      <form
                        data-testid="delete-account-form"
                        onSubmit={(e) => {
                          e.preventDefault();
                          setIsDeleteModalOpen(true);
                        }}
                        className="mt-4 space-y-3 bg-white dark:bg-gray-800 p-4 rounded-md border border-red-500/50"
                      >
                        <p className="text-sm font-medium text-gray-800 dark:text-white">
                          To confirm, please enter your current password.
                        </p>
                        <PasswordInput
                          id="delete-password"
                          value={passwordForDelete}
                          onChange={(e) => setPasswordForDelete(e.target.value)}
                          required
                          placeholder="Enter your password"
                        />
                        <div className="flex flex-col sm:flex-row sm:space-x-2 space-y-2 sm:space-y-0">
                          <button
                            type="button"
                            onClick={() => setIsConfirmingDelete(false)}
                            className="flex-1 bg-gray-200 dark:bg-gray-600 hover:bg-gray-300 dark:hover:bg-gray-500 text-gray-800 dark:text-white font-bold py-2 px-4 rounded-lg shadow-sm transition-colors"
                          >
                            Cancel
                          </button>
                          <button
                            type="submit"
                            disabled={deleteLoading || !passwordForDelete}
                            className="flex-1 bg-red-600 hover:bg-red-700 disabled:bg-red-400 text-white font-bold py-2 px-4 rounded-lg flex justify-center shadow-sm transition-colors"
                          >
                            {deleteLoading ? (
                              <div className="w-5 h-5">
                                <LoadingSpinner />
                              </div>
                            ) : (
                              'Delete Account Permanently'
                            )}
                          </button>
                        </div>
                      </form>
                    )}
                  </div>
                </div>
              )}

              {activeTab === 'preferences' && (
                <div className="space-y-6">
                  <div>
                    <h3 className="text-md font-semibold text-gray-800 dark:text-white">Theme</h3>
                    <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
                      Choose your preferred visual theme.
                    </p>
                    <div className="mt-3 flex items-center">
                      <label htmlFor="darkModeToggle" className="flex items-center cursor-pointer">
                        <div className="relative">
                          <input
                            type="checkbox"
                            id="darkModeToggle"
                            className="sr-only"
                            checked={userProfile?.preferences?.darkMode ?? false}
                            onChange={(e) => handleToggleDarkMode(e.target.checked)}
                          />
                          <div className="block bg-gray-300 dark:bg-gray-600 w-14 h-8 rounded-full"></div>
                          <div className="dot absolute left-1 top-1 bg-white w-6 h-6 rounded-full transition"></div>
                        </div>
                        <div className="ml-3 text-gray-700 dark:text-gray-300 font-medium">
                          Dark Mode
                        </div>
                      </label>
                    </div>
                  </div>

                  <div className="border-t border-gray-200 dark:border-gray-700 pt-4">
                    <h3 className="text-md font-semibold text-gray-800 dark:text-white">
                      Unit System
                    </h3>
                    <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
                      Select your preferred system of measurement.
                    </p>
                    <div className="mt-3 flex space-x-4">
                      <label className="inline-flex items-center">
                        <input
                          type="radio"
                          className="form-radio text-brand-primary"
                          name="unitSystem"
                          value="imperial"
                          checked={userProfile?.preferences?.unitSystem === 'imperial'}
                          onChange={() => handleToggleUnitSystem('imperial')}
                        />
                        <span className="ml-2 text-gray-700 dark:text-gray-300">
                          Imperial (e.g., lbs, oz)
                        </span>
                      </label>
                      <label className="inline-flex items-center">
                        <input
                          type="radio"
                          className="form-radio text-brand-primary"
                          name="unitSystem"
                          value="metric"
                          checked={userProfile?.preferences?.unitSystem === 'metric'}
                          onChange={() => handleToggleUnitSystem('metric')}
                        />
                        <span className="ml-2 text-gray-700 dark:text-gray-300">
                          Metric (e.g., kg, g)
                        </span>
                      </label>
                    </div>
                  </div>
                </div>
              )}
            </div>
          </>
        )}
      </div>
    </div>
  );
};
