import { useState, useEffect } from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { useToast } from '@/hooks/use-toast';
import { supabase } from '@/integrations/supabase/client';
import { Loader2, Shield, CheckCircle2 } from 'lucide-react';
import { InputOTP, InputOTPGroup, InputOTPSlot } from '@/components/ui/input-otp';

const passwordSchema = z.object({
  currentPassword: z.string().min(1, 'Current password is required'),
  newPassword: z.string().min(8, 'Password must be at least 8 characters'),
  confirmPassword: z.string()
}).refine(data => data.newPassword === data.confirmPassword, {
  message: "Passwords don't match",
  path: ["confirmPassword"]
});

type PasswordFormData = z.infer<typeof passwordSchema>;

interface PasswordUpdateDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onSuccess: () => void;
}

type Step = 'password' | 'mfa' | 'success';

export function PasswordUpdateDialog({ open, onOpenChange, onSuccess }: PasswordUpdateDialogProps) {
  const { toast } = useToast();
  const [step, setStep] = useState<Step>('password');
  const [loading, setLoading] = useState(false);
  const [nonce, setNonce] = useState<string>('');
  const [newPassword, setNewPassword] = useState<string>('');
  const [hasMFA, setHasMFA] = useState(false);
  const [totpCode, setTotpCode] = useState('');

  const form = useForm<PasswordFormData>({
    resolver: zodResolver(passwordSchema),
    defaultValues: {
      currentPassword: '',
      newPassword: '',
      confirmPassword: ''
    }
  });

  // Check if user has MFA enabled
  useEffect(() => {
    if (open) {
      checkMFAStatus();
    }
  }, [open]);

  const checkMFAStatus = async () => {
    try {
      const { data, error } = await supabase.auth.mfa.listFactors();
      if (error) throw error;
      
      const hasVerifiedTotp = data?.totp?.some(factor => factor.status === 'verified') || false;
      setHasMFA(hasVerifiedTotp);
    } catch (error) {
      console.error('Error checking MFA status:', error);
    }
  };

  const onSubmit = async (data: PasswordFormData) => {
    setLoading(true);
    try {
      // Step 1: Reauthenticate with current password to get a nonce
      const { error: signInError } = await supabase.auth.signInWithPassword({
        email: (await supabase.auth.getUser()).data.user?.email || '',
        password: data.currentPassword
      });
      
      if (signInError) throw signInError;

      // Step 2: Generate nonce for secure password update
      const { data: sessionData } = await supabase.auth.getSession();
      
      if (!sessionData.session) throw new Error('No active session');

      const generatedNonce = sessionData.session.access_token.substring(0, 32);
      setNonce(generatedNonce);
      setNewPassword(data.newPassword);

      // If user has MFA, require TOTP verification
      if (hasMFA) {
        setStep('mfa');
      } else {
        // No MFA, proceed with password update
        await updatePasswordWithNonce(data.newPassword, generatedNonce);
      }
    } catch (error: any) {
      toast({
        title: 'Authentication Error',
        description: error.message || 'Incorrect password. Please try again.',
        variant: 'destructive'
      });
    } finally {
      setLoading(false);
    }
  };

  const verifyMFAAndUpdate = async () => {
    if (totpCode.length !== 6) {
      toast({
        title: 'Invalid Code',
        description: 'Please enter a valid 6-digit code',
        variant: 'destructive'
      });
      return;
    }

    setLoading(true);
    try {
      // Verify TOTP code
      const { data: challengeData, error: challengeError } = await supabase.auth.mfa.challenge({
        factorId: (await supabase.auth.mfa.listFactors()).data?.totp?.[0]?.id || ''
      });

      if (challengeError) throw challengeError;

      const { error: verifyError } = await supabase.auth.mfa.verify({
        factorId: challengeData.id,
        challengeId: challengeData.id,
        code: totpCode
      });

      if (verifyError) throw verifyError;

      // TOTP verified, now update password
      await updatePasswordWithNonce(newPassword, nonce);
    } catch (error: any) {
      toast({
        title: 'Verification Failed',
        description: error.message || 'Invalid authentication code',
        variant: 'destructive'
      });
    } finally {
      setLoading(false);
    }
  };

  const updatePasswordWithNonce = async (password: string, nonceValue: string) => {
    try {
      // Step 2: Update password
      const { error: updateError } = await supabase.auth.updateUser({
        password
      });

      if (updateError) throw updateError;

      // Step 3: Log audit trail
      const { data: { user } } = await supabase.auth.getUser();
      if (user) {
        await supabase.from('admin_audit_log').insert({
          admin_user_id: user.id,
          target_user_id: user.id,
          action: 'password_changed',
          details: {
            timestamp: new Date().toISOString(),
            method: hasMFA ? 'password_with_mfa' : 'password_only',
            user_agent: navigator.userAgent
          }
        });

        // Step 4: Send security notification
        try {
          await supabase.functions.invoke('trigger-notification', {
            body: {
              workflowId: 'security-alert',
              subscriberId: user.id,
              payload: {
                alert_type: 'password_changed',
                timestamp: new Date().toISOString(),
                device: navigator.userAgent.split(' ')[0]
              }
            }
          });
        } catch (notifError) {
          console.error('Failed to send notification:', notifError);
          // Don't fail the password update if notification fails
        }
      }

      setStep('success');
      form.reset();
      
      // Auto-close after 2 seconds
      setTimeout(() => {
        onOpenChange(false);
        onSuccess();
        setStep('password');
        setTotpCode('');
      }, 2000);
    } catch (error: any) {
      throw error;
    }
  };

  const handleClose = () => {
    if (!loading) {
      onOpenChange(false);
      setStep('password');
      form.reset();
      setTotpCode('');
    }
  };

  return (
    <Dialog open={open} onOpenChange={handleClose}>
      <DialogContent className="sm:max-w-md">
        {step === 'password' && (
          <>
            <DialogHeader>
              <DialogTitle>Change Password</DialogTitle>
              <DialogDescription>
                Enter your current password and choose a new one. {hasMFA && 'You will need to verify with your authenticator app.'}
              </DialogDescription>
            </DialogHeader>

            <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
              <div className="space-y-2">
                <Label htmlFor="currentPassword">Current Password</Label>
                <Input
                  id="currentPassword"
                  type="password"
                  {...form.register('currentPassword')}
                  placeholder="Enter your current password"
                  disabled={loading}
                />
                {form.formState.errors.currentPassword && (
                  <p className="text-sm text-destructive">
                    {form.formState.errors.currentPassword.message}
                  </p>
                )}
              </div>

              <div className="space-y-2">
                <Label htmlFor="newPassword">New Password</Label>
                <Input
                  id="newPassword"
                  type="password"
                  {...form.register('newPassword')}
                  placeholder="Enter your new password"
                  disabled={loading}
                />
                {form.formState.errors.newPassword && (
                  <p className="text-sm text-destructive">
                    {form.formState.errors.newPassword.message}
                  </p>
                )}
              </div>

              <div className="space-y-2">
                <Label htmlFor="confirmPassword">Confirm New Password</Label>
                <Input
                  id="confirmPassword"
                  type="password"
                  {...form.register('confirmPassword')}
                  placeholder="Confirm your new password"
                  disabled={loading}
                />
                {form.formState.errors.confirmPassword && (
                  <p className="text-sm text-destructive">
                    {form.formState.errors.confirmPassword.message}
                  </p>
                )}
              </div>

              <DialogFooter>
                <Button type="button" variant="outline" onClick={handleClose} disabled={loading}>
                  Cancel
                </Button>
                <Button type="submit" disabled={loading}>
                  {loading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
                  {hasMFA ? 'Continue' : 'Update Password'}
                </Button>
              </DialogFooter>
            </form>
          </>
        )}

        {step === 'mfa' && (
          <>
            <DialogHeader>
              <DialogTitle className="flex items-center gap-2">
                <Shield className="h-5 w-5" />
                Verify Your Identity
              </DialogTitle>
              <DialogDescription>
                Enter the 6-digit code from your authenticator app to complete the password change.
              </DialogDescription>
            </DialogHeader>

            <div className="space-y-4 py-4">
              <div className="flex flex-col items-center gap-4">
                <Label htmlFor="totp-code">Authentication Code</Label>
                <InputOTP
                  maxLength={6}
                  value={totpCode}
                  onChange={setTotpCode}
                  disabled={loading}
                >
                  <InputOTPGroup>
                    <InputOTPSlot index={0} />
                    <InputOTPSlot index={1} />
                    <InputOTPSlot index={2} />
                    <InputOTPSlot index={3} />
                    <InputOTPSlot index={4} />
                    <InputOTPSlot index={5} />
                  </InputOTPGroup>
                </InputOTP>
              </div>
            </div>

            <DialogFooter>
              <Button
                variant="outline"
                onClick={() => {
                  setStep('password');
                  setTotpCode('');
                }}
                disabled={loading}
              >
                Back
              </Button>
              <Button onClick={verifyMFAAndUpdate} disabled={loading || totpCode.length !== 6}>
                {loading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
                Verify & Update
              </Button>
            </DialogFooter>
          </>
        )}

        {step === 'success' && (
          <>
            <DialogHeader>
              <DialogTitle className="flex items-center gap-2 text-green-600">
                <CheckCircle2 className="h-5 w-5" />
                Password Updated
              </DialogTitle>
              <DialogDescription>
                Your password has been successfully changed. A security notification has been sent to your email.
              </DialogDescription>
            </DialogHeader>
          </>
        )}
      </DialogContent>
    </Dialog>
  );
}
