import { useState, useEffect } from 'react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Alert, AlertDescription } from '@/components/ui/alert';
import { Badge } from '@/components/ui/badge';
import { handleError, handleSuccess, handleInfo, AppError, getErrorMessage } from '@/lib/errorHandler';
import { logger } from '@/lib/logger';
import { useAuth } from '@/hooks/useAuth';
import { useRequireMFA } from '@/hooks/useRequireMFA';
import { supabase } from '@/integrations/supabase/client';
import { Smartphone, Shield, Copy, Eye, EyeOff, Trash2, AlertTriangle } from 'lucide-react';
import { MFARemovalDialog } from './MFARemovalDialog';
import { setStepUpRequired, getAuthMethod } from '@/lib/sessionFlags';
import { useNavigate } from 'react-router-dom';
import type { MFAFactor } from '@/types/auth';

export function TOTPSetup() {
  const { user } = useAuth();
  const { requiresMFA } = useRequireMFA();
  const navigate = useNavigate();
  const [factors, setFactors] = useState<MFAFactor[]>([]);
  const [loading, setLoading] = useState(false);
  const [enrolling, setEnrolling] = useState(false);
  const [qrCode, setQrCode] = useState('');
  const [secret, setSecret] = useState('');
  const [factorId, setFactorId] = useState('');
  const [verificationCode, setVerificationCode] = useState('');
  const [showSecret, setShowSecret] = useState(false);
  const [showRemovalDialog, setShowRemovalDialog] = useState(false);

  useEffect(() => {
    fetchTOTPFactors();
  }, [user]);

  const fetchTOTPFactors = async () => {
    if (!user) return;

    try {
      const { data, error } = await supabase.auth.mfa.listFactors();
      if (error) throw error;
      
      const totpFactors = (data.totp || []).map(factor => ({
        id: factor.id,
        friendly_name: factor.friendly_name || 'Authenticator App',
        factor_type: 'totp' as const,
        status: factor.status as 'verified' | 'unverified',
        created_at: factor.created_at,
        updated_at: factor.updated_at
      }));
      setFactors(totpFactors);
    } catch (error: unknown) {
      logger.error('Failed to fetch TOTP factors', {
        userId: user?.id,
        action: 'fetch_totp_factors',
        error: getErrorMessage(error)
      });
    }
  };

  const startEnrollment = async () => {
    if (!user) return;

    setLoading(true);
    try {
      const { data, error } = await supabase.auth.mfa.enroll({
        factorType: 'totp',
        friendlyName: 'Authenticator App'
      });

      if (error) throw error;

      setQrCode(data.totp.qr_code);
      setSecret(data.totp.secret);
      setFactorId(data.id);
      setEnrolling(true);
    } catch (error: unknown) {
      logger.error('Failed to start TOTP enrollment', {
        userId: user?.id,
        action: 'totp_enroll_start',
        error: getErrorMessage(error)
      });
      handleError(
        new AppError(
          getErrorMessage(error) || 'Failed to start TOTP enrollment',
          'TOTP_ENROLL_FAILED'
        ),
        { action: 'Start TOTP enrollment', userId: user?.id }
      );
    } finally {
      setLoading(false);
    }
  };

  const verifyAndEnable = async () => {
    if (!factorId || !verificationCode.trim()) {
      handleError(
        new AppError('Please enter the verification code', 'INVALID_INPUT'),
        { action: 'Verify TOTP', userId: user?.id, metadata: { step: 'code_entry' } }
      );
      return;
    }

    setLoading(true);
    try {
      // Step 1: Create a challenge first
      const { data: challengeData, error: challengeError } = await supabase.auth.mfa.challenge({
        factorId
      });

      if (challengeError) throw challengeError;

      // Step 2: Verify using the challengeId from the challenge response
      const { error: verifyError } = await supabase.auth.mfa.verify({
        factorId,
        challengeId: challengeData.id,
        code: verificationCode.trim()
      });

      if (verifyError) throw verifyError;

      // Check if user signed in via OAuth and trigger step-up flow
      const authMethod = getAuthMethod();
      const isOAuthUser = authMethod === 'oauth';
      
      if (isOAuthUser) {
        setStepUpRequired(true, window.location.pathname);
        navigate('/auth/mfa-step-up');
        return;
      }

      handleSuccess(
        'Multi-Factor Authentication Enabled',
        isOAuthUser 
          ? 'Please verify with your authenticator app to continue.' 
          : 'Please sign in again to activate Multi-Factor Authentication protection.'
      );

      if (isOAuthUser) {
        // Already handled above with navigate
        return;
      } else {
        // For email/password users, force sign out to require MFA on next login
        setTimeout(async () => {
          await supabase.auth.signOut();
          window.location.href = '/auth';
        }, 2000);
      }
    } catch (error: unknown) {
      logger.error('TOTP verification failed', {
        userId: user?.id,
        action: 'totp_verify',
        error: getErrorMessage(error),
        factorId
      });
      
      handleError(
        new AppError(
          getErrorMessage(error) || 'Invalid verification code. Please try again.',
          'TOTP_VERIFY_FAILED'
        ),
        { action: 'Verify TOTP code', userId: user?.id, metadata: { factorId } }
      );
    } finally {
      setLoading(false);
    }
  };

  const handleRemovalSuccess = async () => {
    await fetchTOTPFactors();
  };

  const copySecret = () => {
    navigator.clipboard.writeText(secret);
    handleInfo('Copied', 'Secret key copied to clipboard');
  };

  const cancelEnrollment = () => {
    setEnrolling(false);
    setQrCode('');
    setSecret('');
    setFactorId('');
    setVerificationCode('');
  };

  const activeFactor = factors.find(f => f.status === 'verified');

  if (enrolling) {
    return (
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <Smartphone className="w-5 h-5" />
            Set Up Authenticator App
          </CardTitle>
          <CardDescription>
            Scan the QR code with your authenticator app, then enter the verification code below.
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-6">
          {/* QR Code */}
          <div className="flex justify-center">
            <div className="p-4 bg-white rounded-lg border">
              <img src={qrCode} alt="TOTP QR Code" className="w-48 h-48" />
            </div>
          </div>

          {/* Manual Entry */}
          <div className="space-y-2">
            <Label>Can't scan? Enter this key manually:</Label>
            <div className="flex items-center gap-2">
              <Input
                value={secret}
                readOnly
                type={showSecret ? 'text' : 'password'}
                className="font-mono text-sm"
              />
              <Button
                variant="outline"
                size="sm"
                onClick={() => setShowSecret(!showSecret)}
              >
                {showSecret ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
              </Button>
              <Button variant="outline" size="sm" onClick={copySecret}>
                <Copy className="w-4 h-4" />
              </Button>
            </div>
          </div>

          {/* Verification */}
          <div className="space-y-4">
            <div className="space-y-2">
              <Label htmlFor="verificationCode">Enter verification code from your app:</Label>
              <Input
                id="verificationCode"
                value={verificationCode}
                onChange={(e) => setVerificationCode(e.target.value)}
                onPaste={(e) => e.preventDefault()}
                placeholder="000000"
                maxLength={6}
                className="text-center text-lg tracking-widest font-mono"
              />
            </div>

            <div className="flex gap-2 justify-end">
              <Button variant="outline" onClick={cancelEnrollment}>
                Cancel
              </Button>
              <Button onClick={verifyAndEnable} disabled={loading || !verificationCode.trim()}>
                {loading ? 'Verifying...' : 'Enable Multi-Factor Authentication'}
              </Button>
            </div>
          </div>
        </CardContent>
      </Card>
    );
  }

  return (
    <Card>
      <CardHeader>
        <CardDescription>
          Add an extra layer of security to your account with Multi-Factor Authentication.
        </CardDescription>
      </CardHeader>
      <CardContent>
        {activeFactor ? (
          <div className="space-y-4">
            <Alert>
              <Shield className="w-4 h-4" />
              <AlertDescription>
                Multi-Factor Authentication is enabled for your account. You'll be prompted for a code from your authenticator app when signing in.
              </AlertDescription>
            </Alert>

            {/* Phase 2: Warning for role-required users */}
            {requiresMFA && (
              <Alert variant="default" className="border-amber-200 dark:border-amber-800 bg-amber-50 dark:bg-amber-950">
                <AlertTriangle className="w-4 h-4 text-amber-600 dark:text-amber-400" />
                <AlertDescription className="text-amber-800 dark:text-amber-200">
                  Your role requires Multi-Factor Authentication. You cannot disable it.
                </AlertDescription>
              </Alert>
            )}

            <div className="flex items-center justify-between p-4 border rounded-lg">
              <div className="flex items-center gap-3">
                <div className="w-8 h-8 bg-green-50 dark:bg-green-950 rounded-full flex items-center justify-center">
                  <Smartphone className="w-4 h-4 text-green-600 dark:text-green-400" />
                </div>
                <div>
                  <p className="font-medium">{activeFactor.friendly_name || 'Authenticator App'}</p>
                  <p className="text-sm text-muted-foreground">
                    Enabled {new Date(activeFactor.created_at).toLocaleDateString()}
                  </p>
                </div>
              </div>
              <div className="flex items-center gap-2">
                <Badge variant="secondary" className="bg-green-50 dark:bg-green-950 text-green-700 dark:text-green-300">
                  Active
                </Badge>
                <Button 
                  variant="outline" 
                  size="sm"
                  onClick={() => setShowRemovalDialog(true)}
                >
                  <Trash2 className="w-4 h-4 mr-2" />
                  Disable
                </Button>
              </div>
            </div>

            <MFARemovalDialog
              open={showRemovalDialog}
              onOpenChange={setShowRemovalDialog}
              factorId={activeFactor.id}
              onSuccess={handleRemovalSuccess}
            />
          </div>
        ) : (
          <div className="flex items-center justify-between p-4 border rounded-lg">
            <div className="flex items-center gap-3">
              <div className="w-8 h-8 bg-muted rounded-full flex items-center justify-center">
                <Smartphone className="w-4 h-4 text-muted-foreground" />
              </div>
              <div>
                <p className="font-medium">Authenticator App</p>
                <p className="text-sm text-muted-foreground">
                  Use an authenticator app to generate verification codes
                </p>
              </div>
            </div>
            <Button onClick={startEnrollment} disabled={loading}>
              {loading ? 'Setting up...' : 'Set Up'}
            </Button>
          </div>
        )}
      </CardContent>
    </Card>
  );
}