import { useState } from 'react';
import axios from 'axios';

import InputError from '@/components/input-error';
import { Button } from '@/components/ui/button';
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import { Spinner } from '@/components/ui/spinner';
import {
    base64ToBuffer,
    decrypt,
    exportKey,
    getAESKeyFromPBKDF,
    getKeyFromPassword,
    importKey,
} from '@/lib/crypto';
import { getStoredKey, storeKey } from '@/lib/key-storage';

interface UnlockMessageDialogProps {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    onUnlock: (message: string) => void;
    encryptedContent: string;
    iv: string;
    salt: string;
}

export default function UnlockMessageDialog({
    open,
    onOpenChange,
    onUnlock,
    encryptedContent,
    iv,
    salt,
}: UnlockMessageDialogProps) {
    const [password, setPassword] = useState('');
    const [storagePreference, setStoragePreference] = useState<
        'session' | 'persistent'
    >('session');
    const [processing, setProcessing] = useState(false);
    const [error, setError] = useState<string | null>(null);

    async function handleUnlock(e: React.FormEvent<HTMLFormElement>) {
        e.preventDefault();
        setError(null);
        setProcessing(true);

        try {
            const storedKey = getStoredKey();

            let aesKey: CryptoKey;

            if (storedKey) {
                aesKey = await importKey(storedKey);
            } else {
                const saltBuffer = base64ToBuffer(salt);
                const pbkdfKey = await getKeyFromPassword(password);
                aesKey = await getAESKeyFromPBKDF(pbkdfKey, saltBuffer);
            }

            const decrypted = await decrypt(encryptedContent, aesKey, iv);

            if (!storedKey && password) {
                const exportedKey = await exportKey(aesKey);
                storeKey(exportedKey, storagePreference === 'persistent');
            }

            onUnlock(decrypted);
            onOpenChange(false);
        } catch (err) {
            console.error('Decryption error:', err);
            setError(
                'Failed to decrypt message. Please check your password and try again.'
            );
        } finally {
            setProcessing(false);
        }
    }

    return (
        <Dialog open={open} onOpenChange={onOpenChange}>
            <DialogContent>
                <DialogHeader>
                    <DialogTitle>Unlock Encrypted Message</DialogTitle>
                    <DialogDescription>
                        Enter your encryption password to decrypt and view your
                        message.
                    </DialogDescription>
                </DialogHeader>
                <form onSubmit={handleUnlock}>
                    <div className="grid gap-4 py-4">
                        <div className="grid gap-2">
                            <Label htmlFor="unlock-password">
                                Encryption Password
                            </Label>
                            <Input
                                id="unlock-password"
                                type="password"
                                required
                                autoFocus
                                value={password}
                                onChange={(e) => setPassword(e.target.value)}
                                placeholder="Enter your encryption password"
                                disabled={processing}
                            />
                        </div>

                        <div className="grid gap-2">
                            <Label htmlFor="unlock-storage">
                                Storage Preference
                            </Label>
                            <Select
                                value={storagePreference}
                                onValueChange={(value) =>
                                    setStoragePreference(
                                        value as 'session' | 'persistent'
                                    )
                                }
                                disabled={processing}
                            >
                                <SelectTrigger id="unlock-storage">
                                    <SelectValue />
                                </SelectTrigger>
                                <SelectContent>
                                    <SelectItem value="session">
                                        Session only
                                    </SelectItem>
                                    <SelectItem value="persistent">
                                        Keep me logged in
                                    </SelectItem>
                                </SelectContent>
                            </Select>
                        </div>

                        {error && (
                            <div className="rounded-md bg-destructive/15 p-3 text-sm text-destructive">
                                {error}
                            </div>
                        )}
                    </div>
                    <DialogFooter>
                        <Button type="submit" disabled={processing}>
                            {processing && <Spinner />}
                            Unlock
                        </Button>
                    </DialogFooter>
                </form>
            </DialogContent>
        </Dialog>
    );
}

