import React, { useCallback, useEffect, useState } from 'react';
import { ArrowLeft, ChevronRight, LogOut } from 'lucide-react';
import ProfileLogo from '../../Logos/ProfileLogo';
import { useAuth } from '../../../contexts/AuthContext';
import { useSetIsSettingsModalOpen } from '../../../contexts/UIContext';
import { useAppRoute } from '../../../hooks/useAppRoute';
import { Button, Panel, StatusBadge } from '../../ui';
import { Field, PasswordField } from './SettingsFields';
import type { SettingsMessage } from './types';

type AccountView = 'summary' | 'email' | 'password' | 'verify-email';

interface AccountSettingsSectionProps {
  isOpen: boolean;
  onMessageChange: (message: SettingsMessage | null) => void;
}

const sourceBadge = (label: string) => (
  <StatusBadge tone="neutral">{label}</StatusBadge>
);

const AccountSettingsSection: React.FC<AccountSettingsSectionProps> = ({
  isOpen,
  onMessageChange,
}) => {
  const { userInfo, logout, updateEmail, updatePassword, requestVerification, verifyCode } = useAuth();
  const setIsSettingsModalOpen = useSetIsSettingsModalOpen();
  const { setRoute } = useAppRoute();
  const [accountView, setAccountView] = useState<AccountView>('summary');
  const [newEmail, setNewEmail] = useState('');
  const [emailPassword, setEmailPassword] = useState('');
  const [verificationCode, setVerificationCode] = useState('');
  const [pendingEmailChange, setPendingEmailChange] = useState<{ newEmail: string; currentPassword: string } | null>(null);
  const [currentPassword, setCurrentPassword] = useState('');
  const [newPassword, setNewPassword] = useState('');
  const [confirmPassword, setConfirmPassword] = useState('');
  const [isSubmitting, setIsSubmitting] = useState(false);

  const resetAccountForms = useCallback(() => {
    setNewEmail('');
    setEmailPassword('');
    setVerificationCode('');
    setPendingEmailChange(null);
    setCurrentPassword('');
    setNewPassword('');
    setConfirmPassword('');
    onMessageChange(null);
  }, [onMessageChange]);

  useEffect(() => {
    if (!isOpen) {
      setAccountView('summary');
      resetAccountForms();
    }
  }, [isOpen, resetAccountForms]);

  const submitEmailChange = async (event: React.FormEvent) => {
    event.preventDefault();
    setIsSubmitting(true);
    onMessageChange(null);
    try {
      const result = await updateEmail(newEmail, emailPassword);
      if (result.requiresVerification) {
        await requestVerification(newEmail, 'email_change');
        setPendingEmailChange({ newEmail, currentPassword: emailPassword });
        setAccountView('verify-email');
      } else {
        onMessageChange({ tone: 'success', text: 'Email updated.' });
        setAccountView('summary');
      }
    } catch (error) {
      onMessageChange({ tone: 'danger', text: error instanceof Error ? error.message : 'Failed to update email.' });
    } finally {
      setIsSubmitting(false);
    }
  };

  const submitVerification = async (event: React.FormEvent) => {
    event.preventDefault();
    setIsSubmitting(true);
    onMessageChange(null);
    try {
      if (!pendingEmailChange) throw new Error('Missing email change request.');
      await verifyCode(pendingEmailChange.newEmail, verificationCode);
      onMessageChange({ tone: 'success', text: 'Email verified.' });
      resetAccountForms();
      setAccountView('summary');
    } catch (error) {
      onMessageChange({ tone: 'danger', text: error instanceof Error ? error.message : 'Verification failed.' });
    } finally {
      setIsSubmitting(false);
    }
  };

  const submitPasswordChange = async (event: React.FormEvent) => {
    event.preventDefault();
    onMessageChange(null);
    if (newPassword.length < 8) {
      onMessageChange({ tone: 'danger', text: 'Password must be at least 8 characters long.' });
      return;
    }
    if (newPassword !== confirmPassword) {
      onMessageChange({ tone: 'danger', text: 'New passwords do not match.' });
      return;
    }
    setIsSubmitting(true);
    try {
      await updatePassword(currentPassword, newPassword);
      onMessageChange({ tone: 'success', text: 'Password updated.' });
      resetAccountForms();
      setAccountView('summary');
    } catch (error) {
      onMessageChange({ tone: 'danger', text: error instanceof Error ? error.message : 'Failed to update password.' });
    } finally {
      setIsSubmitting(false);
    }
  };

  const handleLogout = async () => {
    setIsSettingsModalOpen(false);
    setRoute({ name: 'home' }, { replace: true });
    await logout();
  };

  if (!userInfo) {
    return (
      <Panel className="space-y-3 p-4">
        <div className="flex items-center justify-between gap-3">
          <div>
            <h3 className="font-semibold text-app-text">Account</h3>
            <p className="text-sm text-app-muted">Sign in to manage account settings and saved preferences.</p>
          </div>
          {sourceBadge('Account')}
        </div>
      </Panel>
    );
  }

  if (accountView === 'email') {
    return (
      <form onSubmit={submitEmailChange} className="space-y-4">
        <Button variant="ghost" size="sm" onClick={() => setAccountView('summary')}>
          <ArrowLeft size={15} /> Back
        </Button>
        <Field label="New email" type="email" value={newEmail} onChange={event => setNewEmail(event.target.value)} required />
        <PasswordField label="Current password" value={emailPassword} onChange={event => setEmailPassword(event.target.value)} required />
        <Button variant="primary" type="submit" disabled={isSubmitting}>Send verification</Button>
      </form>
    );
  }

  if (accountView === 'verify-email') {
    return (
      <form onSubmit={submitVerification} className="space-y-4">
        <Button variant="ghost" size="sm" onClick={() => setAccountView('summary')}>
          <ArrowLeft size={15} /> Back
        </Button>
        <Panel muted className="p-4 text-sm text-app-muted">
          Enter the verification code sent to {pendingEmailChange?.newEmail}.
        </Panel>
        <Field label="Verification code" value={verificationCode} onChange={event => setVerificationCode(event.target.value)} required />
        <Button variant="primary" type="submit" disabled={isSubmitting}>Verify email</Button>
      </form>
    );
  }

  if (accountView === 'password') {
    return (
      <form onSubmit={submitPasswordChange} className="space-y-4">
        <Button variant="ghost" size="sm" onClick={() => setAccountView('summary')}>
          <ArrowLeft size={15} /> Back
        </Button>
        <PasswordField label="Current password" value={currentPassword} onChange={event => setCurrentPassword(event.target.value)} required />
        <PasswordField label="New password" value={newPassword} onChange={event => setNewPassword(event.target.value)} required />
        <PasswordField label="Confirm new password" value={confirmPassword} onChange={event => setConfirmPassword(event.target.value)} required />
        <Button variant="primary" type="submit" disabled={isSubmitting}>Update password</Button>
      </form>
    );
  }

  return (
    <div className="space-y-4">
      <Panel className="flex items-center gap-4 p-4">
        <ProfileLogo name={userInfo.name} email={userInfo.email} size={52} showLabel={false} />
        <div className="min-w-0 flex-1">
          <h3 className="truncate font-semibold text-app-text">{userInfo.name}</h3>
          <p className="truncate text-sm text-app-muted">{userInfo.email}</p>
        </div>
      </Panel>
      <Panel className="divide-y divide-app-border overflow-hidden p-0">
        {([
          { label: 'Change email', onClick: () => setAccountView('email') },
          { label: 'Change password', onClick: () => setAccountView('password') },
        ] as const).map(row => (
          <button
            key={row.label}
            type="button"
            onClick={row.onClick}
            className="flex w-full items-center justify-between px-4 py-3 text-sm font-medium text-app-text transition-colors hover:bg-app-surface-hover"
          >
            {row.label}
            <ChevronRight size={16} className="text-app-muted" />
          </button>
        ))}
      </Panel>
      <button
        type="button"
        onClick={handleLogout}
        className="flex w-full items-center justify-center gap-2 rounded-lg border border-app-border px-4 py-2.5 text-sm font-medium text-danger-text transition-colors hover:bg-danger/10"
      >
        <LogOut size={15} /> Log out
      </button>
    </div>
  );
};

export default AccountSettingsSection;
