/**
 * MFA Setup Page
 * Allows users to enable/disable 2FA, manage phone verification, authenticator app, and backup codes
 */

import React, { useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import {
  getMFAStatus,
  sendPhoneVerification,
  verifyPhone,
  enableSMSMFA,
  setupTOTP,
  verifyTOTPSetup,
  generateBackupCodes,
  disableMFA,
  listTrustedDevices,
  revokeTrustedDevice,
  revokeAllTrustedDevices,
  MFAStatus,
  TrustedDevice,
} from '../api/mfa';
import {
  Shield,
  Smartphone,
  Key,
  AlertCircle,
  CheckCircle,
  Loader2,
  Copy,
  Eye,
  EyeOff,
  Trash2,
  Monitor,
  RefreshCw,
} from 'lucide-react';
import toast from 'react-hot-toast';

const MFASetupPage: React.FC = () => {
  const { t } = useTranslation();
  const queryClient = useQueryClient();

  // State
  const [phoneNumber, setPhoneNumber] = useState('');
  const [verificationCode, setVerificationCode] = useState('');
  const [totpCode, setTotpCode] = useState('');
  const [showBackupCodes, setShowBackupCodes] = useState(false);
  const [backupCodes, setBackupCodes] = useState<string[]>([]);
  const [showDisableModal, setShowDisableModal] = useState(false);
  const [disablePassword, setDisablePassword] = useState('');
  const [totpSetupData, setTotpSetupData] = useState<{
    secret: string;
    qr_code: string;
    provisioning_uri: string;
  } | null>(null);
  const [phoneSent, setPhoneSent] = useState(false);

  // Queries
  const { data: mfaStatus, isLoading: statusLoading } = useQuery({
    queryKey: ['mfa-status'],
    queryFn: getMFAStatus,
  });

  const { data: trustedDevicesData, isLoading: devicesLoading } = useQuery({
    queryKey: ['trusted-devices'],
    queryFn: listTrustedDevices,
    enabled: !!mfaStatus?.mfa_enabled,
  });

  // Mutations
  const sendPhoneCodeMutation = useMutation({
    mutationFn: sendPhoneVerification,
    onSuccess: () => {
      setPhoneSent(true);
      toast.success('Verification code sent!');
    },
    onError: (err: any) => {
      toast.error(err.response?.data?.error || 'Failed to send code');
    },
  });

  const verifyPhoneMutation = useMutation({
    mutationFn: verifyPhone,
    onSuccess: () => {
      toast.success('Phone verified!');
      queryClient.invalidateQueries({ queryKey: ['mfa-status'] });
      setVerificationCode('');
    },
    onError: (err: any) => {
      toast.error(err.response?.data?.error || 'Invalid code');
    },
  });

  const enableSMSMutation = useMutation({
    mutationFn: enableSMSMFA,
    onSuccess: (data) => {
      toast.success('SMS MFA enabled!');
      if (data.backup_codes) {
        setBackupCodes(data.backup_codes);
        setShowBackupCodes(true);
      }
      queryClient.invalidateQueries({ queryKey: ['mfa-status'] });
    },
    onError: (err: any) => {
      toast.error(err.response?.data?.error || 'Failed to enable SMS MFA');
    },
  });

  const setupTOTPMutation = useMutation({
    mutationFn: setupTOTP,
    onSuccess: (data) => {
      setTotpSetupData({
        secret: data.secret,
        qr_code: data.qr_code,
        provisioning_uri: data.provisioning_uri,
      });
    },
    onError: (err: any) => {
      toast.error(err.response?.data?.error || 'Failed to setup authenticator');
    },
  });

  const verifyTOTPMutation = useMutation({
    mutationFn: verifyTOTPSetup,
    onSuccess: (data) => {
      toast.success('Authenticator app configured!');
      if (data.backup_codes) {
        setBackupCodes(data.backup_codes);
        setShowBackupCodes(true);
      }
      setTotpSetupData(null);
      setTotpCode('');
      queryClient.invalidateQueries({ queryKey: ['mfa-status'] });
    },
    onError: (err: any) => {
      toast.error(err.response?.data?.error || 'Invalid code');
    },
  });

  const generateBackupCodesMutation = useMutation({
    mutationFn: generateBackupCodes,
    onSuccess: (data) => {
      setBackupCodes(data.backup_codes);
      setShowBackupCodes(true);
      queryClient.invalidateQueries({ queryKey: ['mfa-status'] });
      toast.success('New backup codes generated!');
    },
    onError: (err: any) => {
      toast.error(err.response?.data?.error || 'Failed to generate codes');
    },
  });

  const disableMFAMutation = useMutation({
    mutationFn: disableMFA,
    onSuccess: () => {
      toast.success('Two-factor authentication disabled');
      setShowDisableModal(false);
      setDisablePassword('');
      queryClient.invalidateQueries({ queryKey: ['mfa-status'] });
    },
    onError: (err: any) => {
      toast.error(err.response?.data?.error || 'Invalid password');
    },
  });

  const revokeDeviceMutation = useMutation({
    mutationFn: revokeTrustedDevice,
    onSuccess: () => {
      toast.success('Device trust revoked');
      queryClient.invalidateQueries({ queryKey: ['trusted-devices'] });
    },
    onError: (err: any) => {
      toast.error(err.response?.data?.error || 'Failed to revoke device');
    },
  });

  const revokeAllDevicesMutation = useMutation({
    mutationFn: revokeAllTrustedDevices,
    onSuccess: () => {
      toast.success('All devices revoked');
      queryClient.invalidateQueries({ queryKey: ['trusted-devices'] });
    },
    onError: (err: any) => {
      toast.error(err.response?.data?.error || 'Failed to revoke devices');
    },
  });

  const copyToClipboard = (text: string) => {
    navigator.clipboard.writeText(text);
    toast.success('Copied to clipboard!');
  };

  if (statusLoading) {
    return (
      <div className="flex items-center justify-center min-h-[400px]">
        <Loader2 className="h-8 w-8 animate-spin text-brand-600" />
      </div>
    );
  }

  const trustedDevices = trustedDevicesData?.devices || [];

  return (
    <div className="max-w-4xl mx-auto p-6 space-y-8">
      {/* Header */}
      <div className="flex items-center gap-4">
        <div className="p-3 bg-brand-100 dark:bg-brand-900/30 rounded-full">
          <Shield className="h-8 w-8 text-brand-600 dark:text-brand-400" />
        </div>
        <div>
          <h1 className="text-2xl font-bold text-gray-900 dark:text-white">
            Two-Factor Authentication
          </h1>
          <p className="text-gray-600 dark:text-gray-400">
            Add an extra layer of security to your account
          </p>
        </div>
        {mfaStatus?.mfa_enabled && (
          <div className="ml-auto flex items-center gap-2 text-green-600 dark:text-green-400">
            <CheckCircle className="h-5 w-5" />
            <span className="font-medium">Enabled</span>
          </div>
        )}
      </div>

      {/* Backup Codes Modal */}
      {showBackupCodes && backupCodes.length > 0 && (
        <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4">
          <div className="bg-white dark:bg-gray-800 rounded-xl max-w-md w-full p-6 space-y-4">
            <div className="flex items-center gap-3">
              <Key className="h-6 w-6 text-amber-500" />
              <h2 className="text-xl font-bold text-gray-900 dark:text-white">
                Save Your Backup Codes
              </h2>
            </div>
            <p className="text-sm text-gray-600 dark:text-gray-400">
              Save these codes in a safe place. Each code can only be used once to access your account if you lose your phone.
            </p>
            <div className="bg-gray-100 dark:bg-gray-700 rounded-lg p-4 font-mono text-sm">
              <div className="grid grid-cols-2 gap-2">
                {backupCodes.map((code, index) => (
                  <div key={index} className="text-gray-800 dark:text-gray-200">
                    {code}
                  </div>
                ))}
              </div>
            </div>
            <div className="flex gap-2">
              <button
                onClick={() => copyToClipboard(backupCodes.join('\n'))}
                className="flex-1 flex items-center justify-center gap-2 px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
              >
                <Copy className="h-4 w-4" />
                Copy All
              </button>
              <button
                onClick={() => setShowBackupCodes(false)}
                className="flex-1 px-4 py-2 bg-brand-600 text-white rounded-lg hover:bg-brand-700 transition-colors"
              >
                I've Saved These
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Disable MFA Modal */}
      {showDisableModal && (
        <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4">
          <div className="bg-white dark:bg-gray-800 rounded-xl max-w-md w-full p-6 space-y-4">
            <h2 className="text-xl font-bold text-gray-900 dark:text-white">
              Disable Two-Factor Authentication
            </h2>
            <p className="text-sm text-gray-600 dark:text-gray-400">
              Enter your password to disable 2FA. This will make your account less secure.
            </p>
            <input
              type="password"
              value={disablePassword}
              onChange={(e) => setDisablePassword(e.target.value)}
              placeholder="Enter your password"
              className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
            />
            <div className="flex gap-2">
              <button
                onClick={() => {
                  setShowDisableModal(false);
                  setDisablePassword('');
                }}
                className="flex-1 px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
              >
                Cancel
              </button>
              <button
                onClick={() => disableMFAMutation.mutate({ password: disablePassword })}
                disabled={!disablePassword || disableMFAMutation.isPending}
                className="flex-1 px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors disabled:opacity-50"
              >
                {disableMFAMutation.isPending ? (
                  <Loader2 className="h-5 w-5 animate-spin mx-auto" />
                ) : (
                  'Disable 2FA'
                )}
              </button>
            </div>
          </div>
        </div>
      )}

      {/* SMS Setup */}
      <div className="bg-white dark:bg-gray-800 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700 p-6">
        <div className="flex items-center gap-3 mb-4">
          <Smartphone className="h-6 w-6 text-blue-500" />
          <h2 className="text-lg font-semibold text-gray-900 dark:text-white">
            SMS Authentication
          </h2>
          {mfaStatus?.phone_verified && (
            <span className="ml-auto text-sm text-green-600 dark:text-green-400 flex items-center gap-1">
              <CheckCircle className="h-4 w-4" />
              Phone verified
            </span>
          )}
        </div>

        {!mfaStatus?.phone_verified ? (
          <div className="space-y-4">
            <p className="text-sm text-gray-600 dark:text-gray-400">
              Verify your phone number to receive verification codes via SMS.
            </p>
            <div className="flex gap-2">
              <input
                type="tel"
                value={phoneNumber}
                onChange={(e) => setPhoneNumber(e.target.value)}
                placeholder="+1 (555) 000-0000"
                className="flex-1 px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
              />
              <button
                onClick={() => sendPhoneCodeMutation.mutate(phoneNumber)}
                disabled={!phoneNumber || sendPhoneCodeMutation.isPending}
                className="px-4 py-2 bg-brand-600 text-white rounded-lg hover:bg-brand-700 transition-colors disabled:opacity-50"
              >
                {sendPhoneCodeMutation.isPending ? (
                  <Loader2 className="h-5 w-5 animate-spin" />
                ) : (
                  'Send Code'
                )}
              </button>
            </div>
            {phoneSent && (
              <div className="flex gap-2">
                <input
                  type="text"
                  value={verificationCode}
                  onChange={(e) => setVerificationCode(e.target.value)}
                  placeholder="6-digit code"
                  maxLength={6}
                  className="flex-1 px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
                />
                <button
                  onClick={() => verifyPhoneMutation.mutate(verificationCode)}
                  disabled={verificationCode.length !== 6 || verifyPhoneMutation.isPending}
                  className="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors disabled:opacity-50"
                >
                  {verifyPhoneMutation.isPending ? (
                    <Loader2 className="h-5 w-5 animate-spin" />
                  ) : (
                    'Verify'
                  )}
                </button>
              </div>
            )}
          </div>
        ) : (
          <div className="space-y-4">
            <p className="text-sm text-gray-600 dark:text-gray-400">
              Your phone ending in {mfaStatus.phone_last_4} is verified.
              {mfaStatus.mfa_method?.includes('SMS') || mfaStatus.mfa_method === 'BOTH'
                ? ' SMS authentication is enabled.'
                : ' Enable SMS to use it for verification.'}
            </p>
            {!(mfaStatus.mfa_method?.includes('SMS') || mfaStatus.mfa_method === 'BOTH') && (
              <button
                onClick={() => enableSMSMutation.mutate()}
                disabled={enableSMSMutation.isPending}
                className="px-4 py-2 bg-brand-600 text-white rounded-lg hover:bg-brand-700 transition-colors disabled:opacity-50"
              >
                {enableSMSMutation.isPending ? (
                  <Loader2 className="h-5 w-5 animate-spin" />
                ) : (
                  'Enable SMS Authentication'
                )}
              </button>
            )}
          </div>
        )}
      </div>

      {/* TOTP Setup */}
      <div className="bg-white dark:bg-gray-800 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700 p-6">
        <div className="flex items-center gap-3 mb-4">
          <Shield className="h-6 w-6 text-purple-500" />
          <h2 className="text-lg font-semibold text-gray-900 dark:text-white">
            Authenticator App
          </h2>
          {mfaStatus?.totp_verified && (
            <span className="ml-auto text-sm text-green-600 dark:text-green-400 flex items-center gap-1">
              <CheckCircle className="h-4 w-4" />
              Configured
            </span>
          )}
        </div>

        {!mfaStatus?.totp_verified ? (
          <div className="space-y-4">
            <p className="text-sm text-gray-600 dark:text-gray-400">
              Use an authenticator app like Google Authenticator, Authy, or 1Password to generate verification codes.
            </p>
            {!totpSetupData ? (
              <button
                onClick={() => setupTOTPMutation.mutate()}
                disabled={setupTOTPMutation.isPending}
                className="px-4 py-2 bg-brand-600 text-white rounded-lg hover:bg-brand-700 transition-colors disabled:opacity-50"
              >
                {setupTOTPMutation.isPending ? (
                  <Loader2 className="h-5 w-5 animate-spin" />
                ) : (
                  'Set Up Authenticator App'
                )}
              </button>
            ) : (
              <div className="space-y-4">
                <div className="flex flex-col md:flex-row gap-6 items-center">
                  <div className="bg-white p-4 rounded-lg">
                    <img
                      src={totpSetupData.qr_code}
                      alt="QR Code"
                      className="w-48 h-48"
                    />
                  </div>
                  <div className="flex-1 space-y-2">
                    <p className="text-sm text-gray-600 dark:text-gray-400">
                      1. Scan this QR code with your authenticator app
                    </p>
                    <p className="text-sm text-gray-600 dark:text-gray-400">
                      2. Or manually enter this key:
                    </p>
                    <div className="flex items-center gap-2">
                      <code className="px-3 py-2 bg-gray-100 dark:bg-gray-700 rounded font-mono text-sm break-all">
                        {totpSetupData.secret}
                      </code>
                      <button
                        onClick={() => copyToClipboard(totpSetupData.secret)}
                        className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded"
                      >
                        <Copy className="h-4 w-4" />
                      </button>
                    </div>
                  </div>
                </div>
                <div className="flex gap-2">
                  <input
                    type="text"
                    value={totpCode}
                    onChange={(e) => setTotpCode(e.target.value.replace(/\D/g, ''))}
                    placeholder="Enter 6-digit code"
                    maxLength={6}
                    className="flex-1 px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
                  />
                  <button
                    onClick={() => verifyTOTPMutation.mutate(totpCode)}
                    disabled={totpCode.length !== 6 || verifyTOTPMutation.isPending}
                    className="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors disabled:opacity-50"
                  >
                    {verifyTOTPMutation.isPending ? (
                      <Loader2 className="h-5 w-5 animate-spin" />
                    ) : (
                      'Verify'
                    )}
                  </button>
                </div>
                <button
                  onClick={() => setTotpSetupData(null)}
                  className="text-sm text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
                >
                  Cancel
                </button>
              </div>
            )}
          </div>
        ) : (
          <p className="text-sm text-gray-600 dark:text-gray-400">
            Your authenticator app is configured and ready to use.
          </p>
        )}
      </div>

      {/* Backup Codes */}
      {mfaStatus?.mfa_enabled && (
        <div className="bg-white dark:bg-gray-800 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700 p-6">
          <div className="flex items-center gap-3 mb-4">
            <Key className="h-6 w-6 text-amber-500" />
            <h2 className="text-lg font-semibold text-gray-900 dark:text-white">
              Backup Codes
            </h2>
          </div>
          <p className="text-sm text-gray-600 dark:text-gray-400 mb-4">
            Backup codes can be used to access your account if you lose your phone.
            You have <strong>{mfaStatus.backup_codes_count}</strong> codes remaining.
            {mfaStatus.backup_codes_generated_at && (
              <span className="block mt-1 text-xs">
                Generated on {new Date(mfaStatus.backup_codes_generated_at).toLocaleDateString()}
              </span>
            )}
          </p>
          <button
            onClick={() => generateBackupCodesMutation.mutate()}
            disabled={generateBackupCodesMutation.isPending}
            className="flex items-center gap-2 px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors disabled:opacity-50"
          >
            {generateBackupCodesMutation.isPending ? (
              <Loader2 className="h-5 w-5 animate-spin" />
            ) : (
              <>
                <RefreshCw className="h-4 w-4" />
                Generate New Codes
              </>
            )}
          </button>
        </div>
      )}

      {/* Trusted Devices */}
      {mfaStatus?.mfa_enabled && (
        <div className="bg-white dark:bg-gray-800 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700 p-6">
          <div className="flex items-center justify-between mb-4">
            <div className="flex items-center gap-3">
              <Monitor className="h-6 w-6 text-gray-500" />
              <h2 className="text-lg font-semibold text-gray-900 dark:text-white">
                Trusted Devices
              </h2>
            </div>
            {trustedDevices.length > 0 && (
              <button
                onClick={() => revokeAllDevicesMutation.mutate()}
                disabled={revokeAllDevicesMutation.isPending}
                className="text-sm text-red-600 hover:text-red-700 dark:text-red-400"
              >
                Revoke All
              </button>
            )}
          </div>
          {devicesLoading ? (
            <div className="flex justify-center py-4">
              <Loader2 className="h-6 w-6 animate-spin text-gray-400" />
            </div>
          ) : trustedDevices.length === 0 ? (
            <p className="text-sm text-gray-500 dark:text-gray-400">
              No trusted devices. When you log in and check "Trust this device", it will appear here.
            </p>
          ) : (
            <div className="space-y-3">
              {trustedDevices.map((device) => (
                <div
                  key={device.id}
                  className="flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-700/50 rounded-lg"
                >
                  <div className="flex items-center gap-3">
                    <Monitor className="h-5 w-5 text-gray-400" />
                    <div>
                      <p className="text-sm font-medium text-gray-900 dark:text-white">
                        {device.name || 'Unknown Device'}
                        {device.is_current && (
                          <span className="ml-2 text-xs text-green-600 dark:text-green-400">
                            (Current)
                          </span>
                        )}
                      </p>
                      <p className="text-xs text-gray-500 dark:text-gray-400">
                        {device.ip_address} • Last used {new Date(device.last_used_at).toLocaleDateString()}
                      </p>
                    </div>
                  </div>
                  <button
                    onClick={() => revokeDeviceMutation.mutate(device.id)}
                    disabled={revokeDeviceMutation.isPending}
                    className="p-2 text-red-600 hover:bg-red-50 dark:hover:bg-red-900/20 rounded"
                  >
                    <Trash2 className="h-4 w-4" />
                  </button>
                </div>
              ))}
            </div>
          )}
        </div>
      )}

      {/* Disable 2FA */}
      {mfaStatus?.mfa_enabled && (
        <div className="bg-red-50 dark:bg-red-900/20 rounded-xl border border-red-200 dark:border-red-800 p-6">
          <h2 className="text-lg font-semibold text-red-800 dark:text-red-200 mb-2">
            Disable Two-Factor Authentication
          </h2>
          <p className="text-sm text-red-700 dark:text-red-300 mb-4">
            Disabling 2FA will make your account less secure. You will no longer need a verification code to log in.
          </p>
          <button
            onClick={() => setShowDisableModal(true)}
            className="px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors"
          >
            Disable 2FA
          </button>
        </div>
      )}
    </div>
  );
};

export default MFASetupPage;
