import { useState, useEffect } from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Textarea } from '@/components/ui/textarea';
import { Label } from '@/components/ui/label';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Separator } from '@/components/ui/separator';
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from '@/components/ui/alert-dialog';
import { useToast } from '@/hooks/use-toast';
import { useAuth } from '@/hooks/useAuth';
import { supabase } from '@/integrations/supabase/client';
import { User, Upload, Trash2, Mail, AlertCircle, X } from 'lucide-react';
import { PhotoUpload } from '@/components/upload/PhotoUpload';
import { notificationService } from '@/lib/notificationService';
import { EmailChangeDialog } from './EmailChangeDialog';
import { Badge } from '@/components/ui/badge';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { toast as sonnerToast } from 'sonner';
import { AccountDeletionDialog } from './AccountDeletionDialog';
import { DeletionStatusBanner } from './DeletionStatusBanner';

const profileSchema = z.object({
  username: z.string().min(3).max(30).regex(/^[a-zA-Z0-9_-]+$/),
  display_name: z.string().max(50).optional(),
  bio: z.string().max(500).optional(),
  preferred_pronouns: z.string().max(20).optional(),
  show_pronouns: z.boolean(),
  preferred_language: z.string()
});

type ProfileFormData = z.infer<typeof profileSchema>;

export function AccountProfileTab() {
  const { user, profile, refreshProfile, pendingEmail, clearPendingEmail } = useAuth();
  const { toast } = useToast();
  const [loading, setLoading] = useState(false);
  const [avatarLoading, setAvatarLoading] = useState(false);
  const [showDeleteDialog, setShowDeleteDialog] = useState(false);
  const [showEmailDialog, setShowEmailDialog] = useState(false);
  const [showCancelEmailDialog, setShowCancelEmailDialog] = useState(false);
  const [cancellingEmail, setCancellingEmail] = useState(false);
  const [avatarUrl, setAvatarUrl] = useState<string>(profile?.avatar_url || '');
  const [avatarImageId, setAvatarImageId] = useState<string>(profile?.avatar_image_id || '');
  const [showDeletionDialog, setShowDeletionDialog] = useState(false);
  const [deletionRequest, setDeletionRequest] = useState<any>(null);

  const form = useForm<ProfileFormData>({
    resolver: zodResolver(profileSchema),
    defaultValues: {
      username: profile?.username || '',
      display_name: profile?.display_name || '',
      bio: profile?.bio || '',
      preferred_pronouns: profile?.preferred_pronouns || '',
      show_pronouns: profile?.show_pronouns || false,
      preferred_language: profile?.preferred_language || 'en'
    }
  });

  // Check for existing deletion request on mount
  useEffect(() => {
    const checkDeletionRequest = async () => {
      if (!user?.id) return;

      const { data, error } = await supabase
        .from('account_deletion_requests')
        .select('*')
        .eq('user_id', user.id)
        .eq('status', 'pending')
        .maybeSingle();

      if (!error && data) {
        setDeletionRequest(data);
      }
    };

    checkDeletionRequest();
  }, [user?.id]);

  const onSubmit = async (data: ProfileFormData) => {
    if (!user) return;
    
    setLoading(true);
    try {
      const usernameChanged = profile?.username !== data.username;
      
      const { error } = await supabase
        .from('profiles')
        .update({
          username: data.username,
          display_name: data.display_name || null,
          bio: data.bio || null,
          preferred_pronouns: data.preferred_pronouns || null,
          show_pronouns: data.show_pronouns,
          preferred_language: data.preferred_language,
          updated_at: new Date().toISOString()
        })
        .eq('user_id', user.id);

      if (error) throw error;

      // Update Novu subscriber if username changed
      if (usernameChanged && notificationService.isEnabled()) {
        await notificationService.updateSubscriber({
          subscriberId: user.id,
          email: user.email,
          firstName: data.username, // Send username as firstName to Novu
        });
      }

      await refreshProfile();
      toast({
        title: 'Profile updated',
        description: 'Your profile has been successfully updated.'
      });
    } catch (error: any) {
      toast({
        title: 'Error',
        description: error.message || 'Failed to update profile',
        variant: 'destructive'
      });
    } finally {
      setLoading(false);
    }
  };

  const handleAvatarUpload = async (urls: string[], imageId?: string) => {
    if (!user || !urls[0]) return;
    
    const newAvatarUrl = urls[0];
    const newImageId = imageId || '';

    // Update local state immediately
    setAvatarUrl(newAvatarUrl);
    setAvatarImageId(newImageId);

    try {
      const { error } = await supabase
        .from('profiles')
        .update({
          avatar_url: newAvatarUrl,
          avatar_image_id: newImageId,
          updated_at: new Date().toISOString()
        })
        .eq('user_id', user.id);

      if (error) throw error;

      await refreshProfile();
      toast({
        title: 'Avatar updated',
        description: 'Your avatar has been successfully updated.'
      });
    } catch (error: any) {
      // Revert local state on error
      setAvatarUrl(profile?.avatar_url || '');
      setAvatarImageId(profile?.avatar_image_id || '');
      toast({
        title: 'Error',
        description: error.message || 'Failed to update avatar',
        variant: 'destructive'
      });
    }
  };

  const handleCancelEmailChange = async () => {
    if (!user?.email || !pendingEmail) return;
    
    setCancellingEmail(true);
    try {
      // Ensure we have a valid session with access token
      const { data: { session }, error: sessionError } = await supabase.auth.getSession();
      
      if (sessionError || !session?.access_token) {
        console.error('Session error:', sessionError);
        throw new Error('Your session has expired. Please refresh the page and try again.');
      }

      // Call the edge function with explicit authorization header
      const { data, error } = await supabase.functions.invoke('cancel-email-change', {
        method: 'POST',
        headers: {
          Authorization: `Bearer ${session.access_token}`,
        },
      });

      if (error) {
        console.error('Edge function error:', error);
        throw error;
      }

      if (!data?.success) {
        throw new Error(data?.error || 'Failed to cancel email change');
      }

      // Clear the pending email state immediately without refreshing session
      clearPendingEmail();

      // Update Novu subscriber back to current email
      if (notificationService.isEnabled()) {
        await notificationService.updateSubscriber({
          subscriberId: user.id,
          email: user.email,
          firstName: profile?.username || user.email.split('@')[0],
        });
      }

      sonnerToast.success('Email change cancelled', {
        description: 'Your email change request has been cancelled.'
      });

      setShowCancelEmailDialog(false);
      await refreshProfile();
    } catch (error: any) {
      sonnerToast.error('Failed to cancel email change', {
        description: error.message || 'An error occurred while cancelling the email change.'
      });
    } finally {
      setCancellingEmail(false);
    }
  };

  const handleDeletionRequested = async () => {
    // Refresh deletion request data
    const { data, error } = await supabase
      .from('account_deletion_requests')
      .select('*')
      .eq('user_id', user!.id)
      .eq('status', 'pending')
      .maybeSingle();

    if (!error && data) {
      setDeletionRequest(data);
    }
  };

  const handleDeletionCancelled = () => {
    setDeletionRequest(null);
  };

  const isDeactivated = (profile as any)?.deactivated || false;

  return (
    <div className="space-y-8">
      {/* Deletion Status Banner */}
      {deletionRequest && (
        <DeletionStatusBanner
          scheduledDate={deletionRequest.scheduled_deletion_at}
          onCancelled={handleDeletionCancelled}
        />
      )}

      {/* Profile Picture */}
      <div className="space-y-4">
        <h3 className="text-lg font-medium">Profile Picture</h3>
        <PhotoUpload
          variant="avatar"
          maxFiles={1}
          maxSizeMB={1}
          existingPhotos={avatarUrl ? [avatarUrl] : []}
          onUploadComplete={handleAvatarUpload}
          currentImageId={avatarImageId}
          onError={(error) => {
            toast({
              title: "Upload Error",
              description: error,
              variant: "destructive"
            });
          }}
        />
      </div>

      <Separator />

      {/* Profile Information */}
      <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
        <h3 className="text-lg font-medium">Profile Information</h3>
        
        <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
          <div className="space-y-2">
            <Label htmlFor="username">Username *</Label>
            <Input
              id="username"
              {...form.register('username')}
              placeholder="Enter your username"
              disabled={isDeactivated}
            />
            {form.formState.errors.username && (
              <p className="text-sm text-destructive">
                {form.formState.errors.username.message}
              </p>
            )}
          </div>

          <div className="space-y-2">
            <Label htmlFor="display_name">Display Name</Label>
            <Input
              id="display_name"
              {...form.register('display_name')}
              placeholder="Enter your display name"
            />
            {form.formState.errors.display_name && (
              <p className="text-sm text-destructive">
                {form.formState.errors.display_name.message}
              </p>
            )}
          </div>
        </div>

        <div className="space-y-2">
          <Label htmlFor="bio">Bio</Label>
          <Textarea
            id="bio"
            {...form.register('bio')}
            placeholder="Tell us about yourself..."
            rows={4}
          />
          {form.formState.errors.bio && (
            <p className="text-sm text-destructive">
              {form.formState.errors.bio.message}
            </p>
          )}
        </div>

        <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
          <div className="space-y-2">
            <Label htmlFor="preferred_pronouns">Preferred Pronouns</Label>
            <Input
              id="preferred_pronouns"
              {...form.register('preferred_pronouns')}
              placeholder="e.g., they/them, she/her, he/him"
            />
          </div>

          <div className="space-y-2">
            <Label htmlFor="preferred_language">Preferred Language</Label>
            <Select
              value={form.watch('preferred_language')}
              onValueChange={(value) => form.setValue('preferred_language', value)}
            >
              <SelectTrigger>
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="en">English</SelectItem>
                <SelectItem value="es">Español</SelectItem>
                <SelectItem value="fr">Français</SelectItem>
                <SelectItem value="de">Deutsch</SelectItem>
                <SelectItem value="it">Italiano</SelectItem>
              </SelectContent>
            </Select>
          </div>
        </div>

        <Button type="submit" disabled={loading || isDeactivated}>
          {loading ? 'Saving...' : 'Save Changes'}
        </Button>
        {isDeactivated && (
          <p className="text-sm text-muted-foreground">
            Your account is deactivated. Profile editing is disabled.
          </p>
        )}
      </form>

      <Separator />

      {/* Account Information */}
      <div className="space-y-4">
        <h3 className="text-lg font-medium">Account Information</h3>
        <div className="space-y-4">
          {pendingEmail && (
            <Alert className="border-blue-500/20 bg-blue-500/10">
              <AlertCircle className="h-4 w-4 text-blue-500" />
              <AlertTitle className="text-blue-500 flex items-center justify-between">
                <span>Email Change in Progress</span>
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={() => setShowCancelEmailDialog(true)}
                  className="h-auto py-1 px-2 text-blue-500 hover:text-blue-600 hover:bg-blue-500/20"
                >
                  <X className="h-4 w-4 mr-1" />
                  Cancel Change
                </Button>
              </AlertTitle>
              <AlertDescription className="text-sm text-muted-foreground">
                You have a pending email change to <strong>{pendingEmail}</strong>.
                Please check both your current email ({user?.email}) and new email ({pendingEmail}) for confirmation links.
                Both must be confirmed to complete the change.
              </AlertDescription>
            </Alert>
          )}
          
          <div className="p-4 bg-muted/50 rounded-lg space-y-4">
            <div className="flex items-center justify-between">
              <div className="flex-1">
                <p className="text-sm font-medium">Email Address</p>
                <div className="flex items-center gap-2 mt-1">
                  <p className="text-sm text-muted-foreground">{user?.email}</p>
                  {pendingEmail ? (
                    <Badge variant="secondary" className="bg-blue-500/10 text-blue-500 border-blue-500/20 text-xs">
                      Change Pending
                    </Badge>
                  ) : user?.email_confirmed_at ? (
                    <Badge variant="secondary" className="text-xs">Verified</Badge>
                  ) : (
                    <Badge variant="outline" className="text-xs">Pending Verification</Badge>
                  )}
                </div>
              </div>
              <Button 
                variant="outline" 
                size="sm"
                onClick={() => setShowEmailDialog(true)}
                disabled={!!pendingEmail}
              >
                <Mail className="w-4 h-4 mr-2" />
                Change Email
              </Button>
            </div>
            
            <Separator />
            
            <div>
              <p className="text-sm font-medium">Account Created</p>
              <p className="text-sm text-muted-foreground mt-1">
                {profile?.created_at ? new Date(profile.created_at).toLocaleDateString() : 'N/A'}
              </p>
            </div>
          </div>
        </div>
      </div>

      {/* Email Change Dialog */}
      {user && (
        <EmailChangeDialog
          open={showEmailDialog}
          onOpenChange={setShowEmailDialog}
          currentEmail={user.email || ''}
          userId={user.id}
        />
      )}

      {/* Cancel Email Change Dialog */}
      <AlertDialog open={showCancelEmailDialog} onOpenChange={setShowCancelEmailDialog}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Cancel Email Change?</AlertDialogTitle>
            <AlertDialogDescription>
              This will cancel your pending email change to <strong>{pendingEmail}</strong>.
              Your email will remain as <strong>{user?.email}</strong>.
              You can start a new email change request at any time.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel disabled={cancellingEmail}>Keep Change</AlertDialogCancel>
            <AlertDialogAction
              onClick={handleCancelEmailChange}
              disabled={cancellingEmail}
              className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
            >
              {cancellingEmail ? 'Cancelling...' : 'Yes, Cancel Change'}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      <Separator />

      {/* Danger Zone */}
      <Card className="border-destructive">
        <CardHeader>
          <CardTitle className="text-destructive">Danger Zone</CardTitle>
          <CardDescription>
            Permanently delete your account with a 2-week waiting period
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="flex items-center justify-between">
            <div className="space-y-1">
              <p className="text-sm font-medium">Delete Account</p>
              <p className="text-sm text-muted-foreground">
                Your profile and reviews will be deleted, but your contributions (submissions, photos) will be preserved
              </p>
            </div>
            <Button
              variant="destructive"
              onClick={() => setShowDeletionDialog(true)}
              disabled={!!deletionRequest}
            >
              <Trash2 className="w-4 h-4 mr-2" />
              {deletionRequest ? 'Deletion Pending' : 'Delete Account'}
            </Button>
          </div>
        </CardContent>
      </Card>

      {/* Account Deletion Dialog */}
      <AccountDeletionDialog
        open={showDeletionDialog}
        onOpenChange={setShowDeletionDialog}
        userEmail={user?.email || ''}
        onDeletionRequested={handleDeletionRequested}
      />
    </div>
  );
}