import React, { useState } from 'react';
import { X, Shield, Copy, Check, Download, AlertTriangle, Smartphone } from 'lucide-react';
import { useSetupTOTP, useVerifyTOTP, useDisableTOTP, useRecoveryCodes, useRegenerateRecoveryCodes } from '../../hooks/useProfile';

interface TwoFactorSetupProps {
  isEnabled: boolean;
  phoneVerified?: boolean;
  hasPhone?: boolean;
  onClose: () => void;
  onSuccess: () => void;
  onVerifyPhone?: () => void;
}

type SetupStep = 'intro' | 'qrcode' | 'verify' | 'recovery' | 'complete' | 'disable' | 'view-recovery';

const TwoFactorSetup: React.FC<TwoFactorSetupProps> = ({ isEnabled, phoneVerified = false, hasPhone = false, onClose, onSuccess, onVerifyPhone }) => {
  const [step, setStep] = useState<SetupStep>(isEnabled ? 'disable' : 'intro');
  const [verificationCode, setVerificationCode] = useState('');
  const [disableCode, setDisableCode] = useState('');
  const [error, setError] = useState('');
  const [copiedSecret, setCopiedSecret] = useState(false);
  const [copiedCodes, setCopiedCodes] = useState(false);

  const setupTOTP = useSetupTOTP();
  const verifyTOTP = useVerifyTOTP();
  const disableTOTP = useDisableTOTP();
  const recoveryCodes = useRecoveryCodes();
  const regenerateCodes = useRegenerateRecoveryCodes();

  const handleStartSetup = async () => {
    setError('');
    try {
      await setupTOTP.mutateAsync();
      setStep('qrcode');
    } catch (err: any) {
      setError(err.response?.data?.detail || 'Failed to start 2FA setup');
    }
  };

  const handleVerify = async () => {
    if (verificationCode.length !== 6) {
      setError('Please enter a 6-digit code');
      return;
    }
    setError('');
    try {
      const result = await verifyTOTP.mutateAsync(verificationCode);
      // Store recovery codes from response
      setStep('recovery');
    } catch (err: any) {
      setError(err.response?.data?.detail || 'Invalid verification code');
    }
  };

  const handleDisable = async () => {
    if (disableCode.length !== 6) {
      setError('Please enter a 6-digit code');
      return;
    }
    setError('');
    try {
      await disableTOTP.mutateAsync(disableCode);
      onSuccess();
      onClose();
    } catch (err: any) {
      setError(err.response?.data?.detail || 'Invalid code');
    }
  };

  const handleViewRecoveryCodes = async () => {
    setError('');
    try {
      await recoveryCodes.refetch();
      setStep('view-recovery');
    } catch (err: any) {
      setError(err.response?.data?.detail || 'Failed to load recovery codes');
    }
  };

  const handleRegenerateCodes = async () => {
    setError('');
    try {
      await regenerateCodes.mutateAsync();
    } catch (err: any) {
      setError(err.response?.data?.detail || 'Failed to regenerate codes');
    }
  };

  const copyToClipboard = (text: string, type: 'secret' | 'codes') => {
    navigator.clipboard.writeText(text);
    if (type === 'secret') {
      setCopiedSecret(true);
      setTimeout(() => setCopiedSecret(false), 2000);
    } else {
      setCopiedCodes(true);
      setTimeout(() => setCopiedCodes(false), 2000);
    }
  };

  const downloadRecoveryCodes = (codes: string[]) => {
    const content = `SmoothSchedule Recovery Codes\n${'='.repeat(30)}\n\nKeep these codes safe. Each code can only be used once.\n\n${codes.join('\n')}\n\nGenerated: ${new Date().toISOString()}`;
    const blob = new Blob([content], { type: 'text/plain' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'smoothschedule-recovery-codes.txt';
    a.click();
    URL.revokeObjectURL(url);
  };

  const handleComplete = () => {
    onSuccess();
    onClose();
  };

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
      <div className="bg-white dark:bg-gray-800 rounded-xl shadow-xl max-w-md w-full mx-4 max-h-[90vh] overflow-y-auto">
        {/* Header */}
        <div className="flex items-center justify-between p-6 border-b border-gray-200 dark:border-gray-700">
          <div className="flex items-center gap-3">
            <div className="p-2 bg-brand-100 dark:bg-brand-900/30 rounded-lg">
              <Shield size={20} className="text-brand-600 dark:text-brand-400" />
            </div>
            <h2 className="text-lg font-semibold text-gray-900 dark:text-white">
              {isEnabled ? 'Manage Two-Factor Authentication' : 'Set Up Two-Factor Authentication'}
            </h2>
          </div>
          <button
            onClick={onClose}
            className="p-2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700"
          >
            <X size={20} />
          </button>
        </div>

        {/* Content */}
        <div className="p-6">
          {error && (
            <div className="mb-4 p-3 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg flex items-center gap-2 text-red-700 dark:text-red-400 text-sm">
              <AlertTriangle size={16} />
              {error}
            </div>
          )}

          {/* Intro Step */}
          {step === 'intro' && (
            <div className="space-y-4">
              <div className="text-center py-4">
                <div className="w-16 h-16 bg-brand-100 dark:bg-brand-900/30 rounded-full flex items-center justify-center mx-auto mb-4">
                  <Smartphone size={32} className="text-brand-600 dark:text-brand-400" />
                </div>
                <h3 className="text-lg font-medium text-gray-900 dark:text-white mb-2">
                  Secure Your Account
                </h3>
                <p className="text-gray-500 dark:text-gray-400 text-sm">
                  Two-factor authentication adds an extra layer of security. You'll need an authenticator app like Google Authenticator or Authy.
                </p>
              </div>

              {/* SMS Backup Info */}
              <div className={`p-4 rounded-lg border ${phoneVerified ? 'bg-green-50 dark:bg-green-900/20 border-green-200 dark:border-green-800' : 'bg-amber-50 dark:bg-amber-900/20 border-amber-200 dark:border-amber-800'}`}>
                <div className="flex items-start gap-3">
                  {phoneVerified ? (
                    <Check size={18} className="text-green-600 dark:text-green-400 mt-0.5" />
                  ) : (
                    <AlertTriangle size={18} className="text-amber-600 dark:text-amber-400 mt-0.5" />
                  )}
                  <div className="flex-1">
                    <p className={`text-sm font-medium ${phoneVerified ? 'text-green-700 dark:text-green-300' : 'text-amber-700 dark:text-amber-300'}`}>
                      SMS Backup {phoneVerified ? 'Available' : 'Not Available'}
                    </p>
                    <p className={`text-xs mt-1 ${phoneVerified ? 'text-green-600 dark:text-green-400' : 'text-amber-600 dark:text-amber-400'}`}>
                      {phoneVerified
                        ? 'Your verified phone can be used as a backup method.'
                        : hasPhone
                          ? 'Your phone number is not verified. Verify it to enable SMS backup as a fallback when you can\'t access your authenticator app.'
                          : 'Add and verify a phone number in your profile settings to receive text message codes as a backup when you can\'t access your authenticator app.'}
                    </p>
                    {!phoneVerified && hasPhone && onVerifyPhone && (
                      <button
                        onClick={() => {
                          onClose();
                          onVerifyPhone();
                        }}
                        className="mt-2 text-xs font-medium text-amber-700 dark:text-amber-300 underline hover:no-underline"
                      >
                        Verify your phone number now
                      </button>
                    )}
                    {!phoneVerified && !hasPhone && (
                      <button
                        onClick={onClose}
                        className="mt-2 text-xs font-medium text-amber-700 dark:text-amber-300 underline hover:no-underline"
                      >
                        Go to profile settings to add a phone number
                      </button>
                    )}
                  </div>
                </div>
              </div>

              <button
                onClick={handleStartSetup}
                disabled={setupTOTP.isPending}
                className="w-full py-3 bg-brand-500 text-white rounded-lg hover:bg-brand-600 transition-colors disabled:opacity-50 font-medium"
              >
                {setupTOTP.isPending ? 'Setting up...' : 'Get Started'}
              </button>
            </div>
          )}

          {/* QR Code Step */}
          {step === 'qrcode' && setupTOTP.data && (
            <div className="space-y-4">
              <div className="text-center">
                <p className="text-sm text-gray-600 dark:text-gray-400 mb-4">
                  Scan this QR code with your authenticator app
                </p>
                <div className="bg-white p-4 rounded-lg inline-block mb-4">
                  <img
                    src={`data:image/png;base64,${setupTOTP.data.qr_code}`}
                    alt="2FA QR Code"
                    className="w-48 h-48"
                  />
                </div>
              </div>

              <div className="bg-gray-50 dark:bg-gray-700/50 rounded-lg p-4">
                <p className="text-xs text-gray-500 dark:text-gray-400 mb-2">
                  Can't scan? Enter this code manually:
                </p>
                <div className="flex items-center gap-2">
                  <code className="flex-1 bg-white dark:bg-gray-800 px-3 py-2 rounded border border-gray-200 dark:border-gray-600 text-sm font-mono text-gray-900 dark:text-white break-all">
                    {setupTOTP.data.secret}
                  </code>
                  <button
                    onClick={() => copyToClipboard(setupTOTP.data!.secret, 'secret')}
                    className="p-2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200"
                    title="Copy to clipboard"
                  >
                    {copiedSecret ? <Check size={18} className="text-green-500" /> : <Copy size={18} />}
                  </button>
                </div>
              </div>

              <button
                onClick={() => setStep('verify')}
                className="w-full py-3 bg-brand-500 text-white rounded-lg hover:bg-brand-600 transition-colors font-medium"
              >
                Continue
              </button>
            </div>
          )}

          {/* Verify Step */}
          {step === 'verify' && (
            <div className="space-y-4">
              <div className="text-center mb-4">
                <p className="text-sm text-gray-600 dark:text-gray-400">
                  Enter the 6-digit code from your authenticator app
                </p>
              </div>

              <input
                type="text"
                value={verificationCode}
                onChange={(e) => setVerificationCode(e.target.value.replace(/\D/g, '').slice(0, 6))}
                placeholder="000000"
                className="w-full text-center text-2xl tracking-widest py-4 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-brand-500 focus:border-transparent font-mono"
                autoFocus
              />

              <div className="flex gap-3">
                <button
                  onClick={() => setStep('qrcode')}
                  className="flex-1 py-3 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors font-medium"
                >
                  Back
                </button>
                <button
                  onClick={handleVerify}
                  disabled={verifyTOTP.isPending || verificationCode.length !== 6}
                  className="flex-1 py-3 bg-brand-500 text-white rounded-lg hover:bg-brand-600 transition-colors disabled:opacity-50 font-medium"
                >
                  {verifyTOTP.isPending ? 'Verifying...' : 'Verify'}
                </button>
              </div>
            </div>
          )}

          {/* Recovery Codes Step */}
          {step === 'recovery' && verifyTOTP.data?.recovery_codes && (
            <div className="space-y-4">
              <div className="text-center mb-4">
                <div className="w-12 h-12 bg-green-100 dark:bg-green-900/30 rounded-full flex items-center justify-center mx-auto mb-3">
                  <Check size={24} className="text-green-600 dark:text-green-400" />
                </div>
                <h3 className="text-lg font-medium text-gray-900 dark:text-white mb-1">
                  2FA Enabled Successfully!
                </h3>
                <p className="text-sm text-gray-500 dark:text-gray-400">
                  Save these recovery codes in a safe place
                </p>
              </div>

              <div className="bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 rounded-lg p-4">
                <div className="flex items-start gap-2 mb-3">
                  <AlertTriangle size={16} className="text-amber-600 dark:text-amber-400 mt-0.5" />
                  <p className="text-sm text-amber-700 dark:text-amber-300">
                    Each code can only be used once. Store them securely - you won't see them again!
                  </p>
                </div>
                <div className="grid grid-cols-2 gap-2 bg-white dark:bg-gray-800 rounded-lg p-3">
                  {verifyTOTP.data.recovery_codes.map((code: string, index: number) => (
                    <code key={index} className="text-sm font-mono text-gray-900 dark:text-white">
                      {code}
                    </code>
                  ))}
                </div>
              </div>

              <div className="flex gap-3">
                <button
                  onClick={() => copyToClipboard(verifyTOTP.data!.recovery_codes.join('\n'), 'codes')}
                  className="flex-1 flex items-center justify-center gap-2 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
                >
                  {copiedCodes ? <Check size={16} className="text-green-500" /> : <Copy size={16} />}
                  {copiedCodes ? 'Copied!' : 'Copy'}
                </button>
                <button
                  onClick={() => downloadRecoveryCodes(verifyTOTP.data!.recovery_codes)}
                  className="flex-1 flex items-center justify-center gap-2 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
                >
                  <Download size={16} />
                  Download
                </button>
              </div>

              <button
                onClick={handleComplete}
                className="w-full py-3 bg-brand-500 text-white rounded-lg hover:bg-brand-600 transition-colors font-medium"
              >
                Done
              </button>
            </div>
          )}

          {/* Complete Step (fallback) */}
          {step === 'complete' && (
            <div className="text-center py-8">
              <div className="w-16 h-16 bg-green-100 dark:bg-green-900/30 rounded-full flex items-center justify-center mx-auto mb-4">
                <Check size={32} className="text-green-600 dark:text-green-400" />
              </div>
              <h3 className="text-lg font-medium text-gray-900 dark:text-white mb-2">
                Two-Factor Authentication Enabled
              </h3>
              <p className="text-gray-500 dark:text-gray-400 text-sm mb-6">
                Your account is now more secure
              </p>
              <button
                onClick={handleComplete}
                className="px-6 py-3 bg-brand-500 text-white rounded-lg hover:bg-brand-600 transition-colors font-medium"
              >
                Close
              </button>
            </div>
          )}

          {/* Disable Step */}
          {step === 'disable' && (
            <div className="space-y-4">
              <div className="space-y-3">
                <button
                  onClick={handleViewRecoveryCodes}
                  disabled={recoveryCodes.isFetching}
                  className="w-full flex items-center justify-between p-4 bg-gray-50 dark:bg-gray-700/50 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors"
                >
                  <span className="font-medium text-gray-900 dark:text-white">View Recovery Codes</span>
                  <span className="text-sm text-gray-500 dark:text-gray-400">
                    {recoveryCodes.isFetching ? 'Loading...' : '→'}
                  </span>
                </button>
              </div>

              <div className="border-t border-gray-200 dark:border-gray-700 pt-4 mt-4">
                <p className="text-sm text-gray-600 dark:text-gray-400 mb-3">
                  To disable 2FA, enter a code from your authenticator app:
                </p>
                <input
                  type="text"
                  value={disableCode}
                  onChange={(e) => setDisableCode(e.target.value.replace(/\D/g, '').slice(0, 6))}
                  placeholder="000000"
                  className="w-full text-center text-xl tracking-widest py-3 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-brand-500 focus:border-transparent font-mono mb-3"
                />
                <button
                  onClick={handleDisable}
                  disabled={disableTOTP.isPending || disableCode.length !== 6}
                  className="w-full py-3 bg-red-500 text-white rounded-lg hover:bg-red-600 transition-colors disabled:opacity-50 font-medium"
                >
                  {disableTOTP.isPending ? 'Disabling...' : 'Disable Two-Factor Authentication'}
                </button>
              </div>
            </div>
          )}

          {/* View Recovery Codes Step */}
          {step === 'view-recovery' && recoveryCodes.data && (
            <div className="space-y-4">
              <button
                onClick={() => setStep('disable')}
                className="text-sm text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200"
              >
                ← Back
              </button>

              <div className="bg-gray-50 dark:bg-gray-700/50 rounded-lg p-4">
                <p className="text-sm text-gray-600 dark:text-gray-400 mb-3">
                  Your recovery codes (each can only be used once):
                </p>
                <div className="grid grid-cols-2 gap-2 bg-white dark:bg-gray-800 rounded-lg p-3">
                  {recoveryCodes.data.map((code: string, index: number) => (
                    <code key={index} className="text-sm font-mono text-gray-900 dark:text-white">
                      {code}
                    </code>
                  ))}
                </div>
              </div>

              <div className="flex gap-3">
                <button
                  onClick={() => copyToClipboard(recoveryCodes.data!.join('\n'), 'codes')}
                  className="flex-1 flex items-center justify-center gap-2 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
                >
                  {copiedCodes ? <Check size={16} className="text-green-500" /> : <Copy size={16} />}
                  {copiedCodes ? 'Copied!' : 'Copy'}
                </button>
                <button
                  onClick={() => downloadRecoveryCodes(recoveryCodes.data!)}
                  className="flex-1 flex items-center justify-center gap-2 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
                >
                  <Download size={16} />
                  Download
                </button>
              </div>

              <button
                onClick={handleRegenerateCodes}
                disabled={regenerateCodes.isPending}
                className="w-full py-2 text-amber-600 dark:text-amber-400 hover:bg-amber-50 dark:hover:bg-amber-900/20 rounded-lg transition-colors text-sm"
              >
                {regenerateCodes.isPending ? 'Regenerating...' : 'Regenerate Recovery Codes'}
              </button>
            </div>
          )}
        </div>
      </div>
    </div>
  );
};

export default TwoFactorSetup;
