import React, { useState, useEffect, useRef } from 'react';
import { Download, Key, Copy, Upload } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Textarea } from '@/components/ui/textarea';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog.tsx';
import { toast } from '@/hooks/useToast';
import { useLoginActions } from '@/hooks/useLoginActions';
import { useNostrPublish } from '@/hooks/useNostrPublish';
import { useUploadFile } from '@/hooks/useUploadFile';
import { generateSecretKey, nip19 } from 'nostr-tools';

interface SignupDialogProps {
  isOpen: boolean;
  onClose: () => void;
}

const SignupDialog: React.FC<SignupDialogProps> = ({ isOpen, onClose }) => {
  const [step, setStep] = useState<'generate' | 'download' | 'profile' | 'done'>('generate');
  const [isLoading, setIsLoading] = useState(false);
  const [nsec, setNsec] = useState('');
  const [keySecured, setKeySecured] = useState<'none' | 'copied' | 'downloaded'>('none');
  const [profileData, setProfileData] = useState({
    name: '',
    about: '',
    picture: ''
  });
  const login = useLoginActions();
  const { mutateAsync: publishEvent, isPending: isPublishing } = useNostrPublish();
  const { mutateAsync: uploadFile, isPending: isUploading } = useUploadFile();
  const avatarFileInputRef = useRef<HTMLInputElement>(null);

  const generateKey = () => {
    setIsLoading(true);
    setTimeout(() => {
      try {
        const sk = generateSecretKey();
        setNsec(nip19.nsecEncode(sk));
        setStep('download');
        toast({
          title: 'Key Generated',
          description: 'Your new key is ready.',
        });
      } catch {
        toast({
          title: 'Error',
          description: 'Failed to generate key. Please try again.',
          variant: 'destructive',
        });
      } finally {
        setIsLoading(false);
      }
    }, 500);
  };

  const downloadKey = () => {
    try {
      const blob = new Blob([nsec], { type: 'text/plain; charset=utf-8' });
      const url = globalThis.URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = 'nsec.txt';
      a.style.display = 'none';
      document.body.appendChild(a);
      a.click();
      globalThis.URL.revokeObjectURL(url);
      document.body.removeChild(a);
      setKeySecured('downloaded');
      toast({
        title: 'Key Downloaded',
        description: 'Your key has been saved to a file.',
      });
    } catch {
      toast({
        title: 'Download failed',
        description: 'Could not download the key file. Please copy it manually.',
        variant: 'destructive',
      });
    }
  };

  const copyKey = () => {
    navigator.clipboard.writeText(nsec);
    setKeySecured('copied');
    toast({
      title: 'Copied to clipboard',
      description: 'Your key has been copied.',
    });
  };

  const finishKeySetup = () => {
    try {
      login.nsec(nsec);
      setStep('profile');
    } catch {
      toast({
        title: 'Login Failed',
        description: 'Failed to login with the generated key. Please try again.',
        variant: 'destructive',
      });
    }
  };

  const handleAvatarUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;

    e.target.value = '';

    if (!file.type.startsWith('image/')) {
      toast({
        title: 'Invalid file type',
        description: 'Please select an image file.',
        variant: 'destructive',
      });
      return;
    }

    if (file.size > 5 * 1024 * 1024) {
      toast({
        title: 'File too large',
        description: 'Image must be smaller than 5MB.',
        variant: 'destructive',
      });
      return;
    }

    try {
      const tags = await uploadFile(file);
      const url = tags[0]?.[1];
      if (url) {
        setProfileData(prev => ({ ...prev, picture: url }));
        toast({
          title: 'Avatar uploaded!',
          description: 'Your new avatar is ready.',
        });
      }
    } catch {
      toast({
        title: 'Upload failed',
        description: 'Failed to upload avatar. Please try again.',
        variant: 'destructive',
      });
    }
  };

  const finishSignup = async (skipProfile = false) => {
    try {
      if (!skipProfile && (profileData.name || profileData.about || profileData.picture)) {
        const metadata: Record<string, string> = {};
        if (profileData.name) metadata.name = profileData.name;
        if (profileData.about) metadata.about = profileData.about;
        if (profileData.picture) metadata.picture = profileData.picture;

        await publishEvent({
          kind: 0,
          content: JSON.stringify(metadata),
        });

        toast({
          title: 'Profile Updated',
          description: 'Your profile has been published.',
        });
      }

      setStep('done');
      setTimeout(() => {
        onClose();
        toast({
          title: 'Welcome!',
          description: 'You are now logged in.',
        });
      }, 1500);

    } catch {
      toast({
        title: 'Profile Setup Failed',
        description: 'Your account was created but profile setup failed. You can update it later.',
        variant: 'destructive',
      });

      setStep('done');
      setTimeout(() => {
        onClose();
        toast({
          title: 'Welcome!',
          description: 'You are now logged in.',
        });
      }, 1500);
    }
  };

  useEffect(() => {
    if (isOpen) {
      setStep('generate');
      setIsLoading(false);
      setNsec('');
      setKeySecured('none');
      setProfileData({ name: '', about: '', picture: '' });
    }
  }, [isOpen]);

  const getTitle = () => {
    if (step === 'generate') return 'Create Your Account';
    if (step === 'download') return 'Save Your Key';
    if (step === 'profile') return 'Set Up Your Profile';
    return 'Welcome!';
  };

  const getDescription = () => {
    if (step === 'generate') return "We'll generate a secure, private key for your new account.";
    if (step === 'download') return "This key is your password. It's the only way to access your account.";
    if (step === 'profile') return "Customize your profile. This is how others will see you.";
    return "You're all set up and ready to go.";
  };

  return (
    <Dialog open={isOpen} onOpenChange={onClose}>
      <DialogContent className='sm:max-w-md p-0 overflow-hidden rounded-2xl'>
        <DialogHeader className='px-6 pt-6 pb-2'>
          <DialogTitle className='text-xl font-semibold text-center'>{getTitle()}</DialogTitle>
          <DialogDescription className='text-center text-muted-foreground mt-1'>
            {getDescription()}
          </DialogDescription>
        </DialogHeader>

        <div className='px-6 py-6 space-y-6'>
          {step === 'generate' && (
            <div className='text-center space-y-6'>
              <div className='p-6 rounded-lg bg-gray-50 dark:bg-gray-800 flex items-center justify-center'>
                <Key className='w-16 h-16 text-primary' />
              </div>
              <p className='text-sm text-gray-600 dark:text-gray-300'>
                Click the button below to generate a unique and secure key for your account.
              </p>
              <Button
                className='w-full rounded-full py-6'
                onClick={generateKey}
                disabled={isLoading}
              >
                {isLoading ? 'Generating...' : 'Generate My Key'}
              </Button>
            </div>
          )}

          {step === 'download' && (
            <div className='space-y-6'>
              <div className='p-4 rounded-lg border bg-gray-50 dark:bg-gray-800'>
                <code className='text-sm break-all'>{nsec}</code>
              </div>

              <div className='text-sm text-red-600 dark:text-red-400 space-y-2 bg-red-50 dark:bg-red-900/20 p-3 rounded-lg'>
                <p className='font-medium'>Important:</p>
                <ul className='list-disc pl-5 space-y-1'>
                  <li>Store this key somewhere safe.</li>
                  <li>If you lose it, you lose your account.</li>
                  <li>Never share it with anyone.</li>
                </ul>
              </div>

              <div className='grid grid-cols-2 gap-3'>
                <Button variant='outline' onClick={copyKey}>
                  <Copy className='w-4 h-4 mr-2' />
                  Copy
                </Button>
                <Button variant='outline' onClick={downloadKey}>
                  <Download className='w-4 h-4 mr-2' />
                  Download
                </Button>
              </div>

              <Button
                className='w-full rounded-full py-6'
                onClick={finishKeySetup}
                disabled={keySecured === 'none'}
              >
                I've Saved My Key, Continue
              </Button>
            </div>
          )}

          {step === 'profile' && (
            <div className='space-y-4'>
              <div className={`space-y-4 ${isPublishing || isUploading ? 'opacity-50 pointer-events-none' : ''}`}>
                <div className='space-y-2'>
                  <label htmlFor='profile-name' className='text-sm font-medium'>Display Name</label>
                  <Input
                    id='profile-name'
                    value={profileData.name}
                    onChange={(e) => setProfileData(prev => ({ ...prev, name: e.target.value }))}
                    placeholder='e.g. Satoshi Nakamoto'
                  />
                </div>

                <div className='space-y-2'>
                  <label htmlFor='profile-about' className='text-sm font-medium'>About</label>
                  <Textarea
                    id='profile-about'
                    value={profileData.about}
                    onChange={(e) => setProfileData(prev => ({ ...prev, about: e.target.value }))}
                    placeholder='A short bio...'
                    rows={3}
                  />
                </div>

                <div className='space-y-2'>
                  <label htmlFor='profile-picture' className='text-sm font-medium'>Avatar URL or Upload</label>
                  <div className='flex gap-2'>
                    <Input
                      id='profile-picture'
                      value={profileData.picture}
                      onChange={(e) => setProfileData(prev => ({ ...prev, picture: e.target.value }))}
                      placeholder='https://your-avatar.com/image.jpg'
                    />
                    <input
                      type='file'
                      accept='image/*'
                      className='hidden'
                      ref={avatarFileInputRef}
                      onChange={handleAvatarUpload}
                    />
                    <Button
                      type='button'
                      variant='outline'
                      size='icon'
                      onClick={() => avatarFileInputRef.current?.click()}
                      disabled={isUploading}
                    >
                      {isUploading ? (
                        <div className='w-4 h-4 border-2 border-current border-t-transparent rounded-full animate-spin' />
                      ) : (
                        <Upload className='w-4 h-4' />
                      )}
                    </Button>
                  </div>
                </div>
              </div>

              <div className='flex flex-col space-y-3 pt-4'>
                <Button
                  className='w-full rounded-full py-6'
                  onClick={() => finishSignup(false)}
                  disabled={isPublishing || isUploading}
                >
                  {isPublishing ? 'Publishing...' : 'Finish Signup'}
                </Button>
                <Button
                  variant='ghost'
                  className='w-full'
                  onClick={() => finishSignup(true)}
                  disabled={isPublishing || isUploading}
                >
                  Skip For Now
                </Button>
              </div>
            </div>
          )}

          {step === 'done' && (
            <div className='flex justify-center items-center py-12'>
              <div className='animate-spin rounded-full h-12 w-12 border-b-2 border-primary'></div>
            </div>
          )}
        </div>
      </DialogContent>
    </Dialog>
  );
};

export default SignupDialog;
