import { useState, useEffect } from 'react';
import { invokeWithTracking } from '@/lib/edgeFunctionTracking';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/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 { 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 { useAuth } from '@/hooks/useAuth';
import { useProfile } from '@/hooks/useProfile';
import { supabase } from '@/lib/supabaseClient';
import { Trash2, Mail, AlertCircle, X, Check, Loader2 } 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 { AccountDeletionDialog } from './AccountDeletionDialog';
import { DeletionStatusBanner } from './DeletionStatusBanner';
import { EmailChangeStatus } from './EmailChangeStatus';
import { usernameSchema, displayNameSchema, bioSchema } from '@/lib/validation';
import { z } from 'zod';
import { AccountDeletionRequest } from '@/types/database';
import { handleError, handleSuccess, AppError } from '@/lib/errorHandler';
import { useAvatarUpload } from '@/hooks/useAvatarUpload';
import { useUsernameValidation } from '@/hooks/useUsernameValidation';
import { useAutoSave } from '@/hooks/useAutoSave';
import { formatDistanceToNow } from 'date-fns';
import { cn } from '@/lib/utils';

const profileSchema = z.object({
  username: usernameSchema,
  display_name: displayNameSchema,
  bio: bioSchema
});

type ProfileFormData = z.infer<typeof profileSchema>;

export function AccountProfileTab() {
  const { user, pendingEmail, clearPendingEmail } = useAuth();
  const { data: profile, refreshProfile } = useProfile(user?.id);
  const [loading, setLoading] = useState(false);
  const [showDeleteDialog, setShowDeleteDialog] = useState(false);
  const [showEmailDialog, setShowEmailDialog] = useState(false);
  const [showCancelEmailDialog, setShowCancelEmailDialog] = useState(false);
  const [cancellingEmail, setCancellingEmail] = useState(false);
  const [showDeletionDialog, setShowDeletionDialog] = useState(false);
  const [deletionRequest, setDeletionRequest] = useState<AccountDeletionRequest | null>(null);

  // Initialize avatar upload hook
  const { avatarUrl, avatarImageId, isUploading: avatarLoading, uploadAvatar } = useAvatarUpload(
    profile?.avatar_url || '',
    profile?.avatar_image_id || '',
    profile?.username || ''
  );

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

  // Username validation
  const usernameValue = form.watch('username');
  const usernameValidation = useUsernameValidation(usernameValue, profile?.username);

  // Auto-save (disabled for now - can be enabled per user preference)
  const formData = form.watch();
  const { isSaving, lastSaved } = useAutoSave({
    data: formData,
    onSave: async (data) => {
      const isValid = await form.trigger();
      if (!isValid || usernameValidation.isAvailable === false) return;
      await handleFormSubmit(data);
    },
    debounceMs: 3000,
    enabled: false, // TODO: Get from user preferences
    isValid: usernameValidation.isAvailable !== false
  });

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

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

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

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

  const handleFormSubmit = async (data: ProfileFormData) => {
    if (!user) return;
    
    setLoading(true);
    try {
      // Use the update_profile RPC function with server-side validation
      const { data: result, error } = await supabase.rpc('update_profile', {
        p_username: data.username,
        p_display_name: data.display_name || '',
        p_bio: data.bio || ''
      });

      if (error) {
        // Handle rate limiting error
        if (error.code === 'P0001') {
          const resetTime = error.message.match(/Try again at (.+)$/)?.[1];
          throw new AppError(
            error.message,
            'RATE_LIMIT',
            `Too many profile updates. ${resetTime ? 'Try again at ' + new Date(resetTime).toLocaleTimeString() : 'Please wait a few minutes.'}`
          );
        }
        throw error;
      }

      // Type the RPC result
      const rpcResult = result as unknown as { success: boolean; changes_count: number };

      // Update Novu subscriber if username changed
      if (rpcResult?.changes_count > 0 && notificationService.isEnabled()) {
        await notificationService.updateSubscriber({
          subscriberId: user.id,
          email: user.email,
          firstName: data.username,
        });
      }

      await refreshProfile();
      handleSuccess('Profile updated', 'Your profile has been successfully updated.');
    } catch (error: unknown) {
      handleError(error, { action: 'Update profile', userId: user.id });
    } finally {
      setLoading(false);
    }
  };

  const onSubmit = async (data: ProfileFormData) => {
    await handleFormSubmit(data);
  };

  const handleAvatarUpload = async (urls: string[], imageId?: string) => {
    await uploadAvatar(urls, imageId);
    await refreshProfile();
  };

  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) {
        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, requestId } = await invokeWithTracking(
        'cancel-email-change',
        {},
        user.id
      );

      if (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],
        });
      }

      handleSuccess('Email change cancelled', 'Your email change request has been cancelled.');

      setShowCancelEmailDialog(false);
      await refreshProfile();
    } catch (error: unknown) {
      handleError(error, { action: 'Cancel email change' });
    } finally {
      setCancellingEmail(false);
    }
  };

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

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

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

  const isDeactivated = profile?.deactivated || false;

  return (
    <div className="space-y-6">
      {/* Deletion Status Banner */}
      {deletionRequest && (
        <DeletionStatusBanner
          scheduledDate={deletionRequest.scheduled_deletion_at}
          status={deletionRequest.status as 'pending' | 'confirmed'}
          onCancelled={handleDeletionCancelled}
        />
      )}

      {/* Profile Picture + Account Info Grid */}
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
        {/* Profile Picture */}
        <Card>
          <CardHeader>
            <CardTitle>Profile Picture</CardTitle>
            <CardDescription>Upload your profile picture</CardDescription>
          </CardHeader>
          <CardContent>
            <PhotoUpload
              variant="avatar"
              maxFiles={1}
              maxSizeMB={1}
              existingPhotos={avatarUrl ? [avatarUrl] : []}
              onUploadComplete={handleAvatarUpload}
              currentImageId={avatarImageId}
              onError={(error) => {
                handleError(new Error(error), { action: 'Upload avatar' });
              }}
            />
          </CardContent>
        </Card>

        {/* Account Information */}
        <Card>
          <CardHeader>
            <CardTitle>Account Information</CardTitle>
            <CardDescription>View your account details</CardDescription>
          </CardHeader>
          <CardContent className="space-y-4">
            {pendingEmail && (
              <EmailChangeStatus
                currentEmail={user?.email || ''}
                pendingEmail={pendingEmail}
                onCancel={() => setShowCancelEmailDialog(true)}
              />
            )}
            
            <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
                </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>
          </CardContent>
        </Card>
      </div>

      {/* Profile Information */}
      <Card>
        <CardHeader>
          <CardTitle>Profile Information</CardTitle>
          <CardDescription>Update your public profile details</CardDescription>
        </CardHeader>
        <CardContent>
          <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
            <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
              <div className="space-y-2">
                <Label htmlFor="username">
                  Username *
                  {usernameValidation.isChecking && (
                    <Loader2 className="inline ml-2 w-3 h-3 animate-spin" />
                  )}
                </Label>
                <Input
                  id="username"
                  {...form.register('username')}
                  placeholder="Enter your username"
                  disabled={isDeactivated}
                  className={cn(
                    usernameValidation.error && !form.formState.errors.username && "border-destructive",
                    usernameValidation.isAvailable && "border-green-500"
                  )}
                />
                {usernameValidation.isChecking ? (
                  <p className="text-sm text-muted-foreground">
                    Checking availability...
                  </p>
                ) : usernameValidation.isAvailable === false && !form.formState.errors.username ? (
                  <p className="text-sm text-destructive flex items-center gap-1">
                    <X className="w-3 h-3" />
                    {usernameValidation.error}
                  </p>
                ) : usernameValidation.isAvailable === true && !form.formState.errors.username ? (
                  <p className="text-sm text-green-600 flex items-center gap-1">
                    <Check className="w-3 h-3" />
                    Username is available
                  </p>
                ) : form.formState.errors.username ? (
                  <p className="text-sm text-destructive">
                    {form.formState.errors.username.message}
                  </p>
                ) : null}
              </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="flex items-center justify-between">
              <Button 
                type="submit" 
                disabled={
                  loading || 
                  isDeactivated || 
                  isSaving ||
                  usernameValidation.isChecking ||
                  usernameValidation.isAvailable === false
                }
              >
                {loading || isSaving ? 'Saving...' : 'Save Changes'}
              </Button>
              
              {lastSaved && !loading && !isSaving && (
                <span className="text-sm text-muted-foreground">
                  Last saved {formatDistanceToNow(lastSaved, { addSuffix: true })}
                </span>
              )}
            </div>
            {isDeactivated && (
              <p className="text-sm text-muted-foreground">
                Your account is deactivated. Profile editing is disabled.
              </p>
            )}
          </form>
        </CardContent>
      </Card>

      {/* 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>

      {/* 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>
  );
}