import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { Clock, Globe, Loader2, Lock, Mail } from 'lucide-react';
import { useEffect, useState } from 'react';
import { toast } from 'sonner';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Separator } from '@/components/ui/separator';
import { Switch } from '@/components/ui/switch';
import { apiUserChangePassword, apiEmailChange, apiEmailGet, getPreferences, updatePreferences } from '@/client';
import {getApiErrorMessage} from '@/lib/api-error';

const LANGUAGES = [
    { value: 'en', label: 'English' },
    { value: 'es', label: 'Español' },
    { value: 'fr', label: 'Français' },
    { value: 'zh', label: '中文' },
    { value: 'ja', label: '日本語' },
];

const THEMES = [
    { value: 'light', label: 'Light' },
    { value: 'dark', label: 'Dark' },
    { value: 'system', label: 'System' },
];

const TIMEZONES = [
    { value: 'UTC', label: 'UTC' },
    { value: 'America/New_York', label: 'Eastern Time (ET)' },
    { value: 'America/Chicago', label: 'Central Time (CT)' },
    { value: 'America/Denver', label: 'Mountain Time (MT)' },
    { value: 'America/Los_Angeles', label: 'Pacific Time (PT)' },
    { value: 'Europe/London', label: 'London (GMT)' },
    { value: 'Europe/Paris', label: 'Paris (CET)' },
    { value: 'Asia/Shanghai', label: 'Shanghai (CST)' },
    { value: 'Asia/Tokyo', label: 'Tokyo (JST)' },
];

export function SettingsAccount() {
    const queryClient = useQueryClient();

    // Password change state
    const [oldPassword, setOldPassword] = useState('');
    const [newPassword, setNewPassword] = useState('');
    const [confirmPassword, setConfirmPassword] = useState('');

    // Email change state
    const [newEmail, setNewEmail] = useState('');
    const [emailPassword, setEmailPassword] = useState('');

    // Preferences state
    const [language, setLanguage] = useState('en');
    const [theme, setTheme] = useState<'light' | 'dark' | 'system'>('system');
    const [timezone, setTimezone] = useState('UTC');
    const [emailNotifications, setEmailNotifications] = useState(true);
    const [inAppNotifications, setInAppNotifications] = useState(true);

    const { data: emailData } = useQuery({
        queryKey: ['userEmail'],
        queryFn: async () => {
            const resp = await apiEmailGet();
            return resp.data?.data ?? null;
        },
        retry: false,
        staleTime: 0,
    });

    const {
        data: preferences,
        isLoading,
        isError,
    } = useQuery({
        queryKey: ['userPreferences'],
        queryFn: async () => {
            const resp = await getPreferences();
            return resp.data?.data ?? null;
        },
        retry: false,
        staleTime: 0,
        refetchOnMount: true,
    });

    useEffect(() => {
        if (!preferences) return;

        setLanguage(preferences.language || 'en');
        setTheme((preferences.theme as 'light' | 'dark' | 'system') || 'system');
        setTimezone(preferences.timezone || 'UTC');
        setEmailNotifications(preferences.email_notifications ?? true);
        setInAppNotifications(preferences.in_app_notifications ?? true);
    }, [preferences]);

    // Change password mutation
    const changePasswordMutation = useMutation({
        mutationFn: async () => {
            await apiUserChangePassword({
                body: {
                    old_password: oldPassword,
                    new_password: newPassword,
                },
            });
        },
        onSuccess: () => {
            toast.success('Password changed successfully');
            setOldPassword('');
            setNewPassword('');
            setConfirmPassword('');
        },
        onError: (err: unknown) => {
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            toast.error(getApiErrorMessage(err, 'Failed to change password'));
        },
    });

    const updatePreferencesMutation = useMutation({
        mutationFn: async () => {
            await updatePreferences({
                body: {
                    language,
                    theme,
                    timezone,
                    email_notifications: emailNotifications,
                    in_app_notifications: inAppNotifications,
                },
            });
        },
        onSuccess: () => {
            toast.success('Preferences updated successfully');
            queryClient.invalidateQueries({ queryKey: ['userPreferences'] });
        },
        onError: (err: unknown) => {
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            toast.error(getApiErrorMessage(err, 'Failed to update preferences'));
        },
    });

    const changeEmailMutation = useMutation({
        mutationFn: async () => {
            await apiEmailChange({
                body: {
                    new_email: newEmail,
                    password: emailPassword,
                },
            });
        },
        onSuccess: () => {
            toast.success('Verification email sent! Please check your new email to confirm.');
            setNewEmail('');
            setEmailPassword('');
            queryClient.invalidateQueries({ queryKey: ['userEmail'] });
        },
        onError: (err: unknown) => {
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            toast.error(getApiErrorMessage(err, 'Failed to request email change'));
        },
    });

    const handleChangePassword = (e: React.FormEvent) => {
        e.preventDefault();

        if (!oldPassword) {
            toast.error('Please enter your current password');
            return;
        }
        if (!newPassword) {
            toast.error('Please enter a new password');
            return;
        }
        if (newPassword.length < 8) {
            toast.error('New password must be at least 8 characters');
            return;
        }
        if (newPassword !== confirmPassword) {
            toast.error('Passwords do not match');
            return;
        }

        changePasswordMutation.mutate();
    };

    const handleUpdatePreferences = (e: React.FormEvent) => {
        e.preventDefault();
        updatePreferencesMutation.mutate();
    };

    const handleChangeEmail = (e: React.FormEvent) => {
        e.preventDefault();
        if (!newEmail.trim()) {
            toast.error('Please enter a new email address');
            return;
        }
        const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        if (!emailRegex.test(newEmail)) {
            toast.error('Please enter a valid email address');
            return;
        }
        if (!emailPassword) {
            toast.error('Please enter your password to confirm');
            return;
        }
        changeEmailMutation.mutate();
    };

    if (isLoading) {
        return (
            <div className="px-8 py-6">
                <div className="flex items-center justify-center py-12">
                    <Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
                </div>
            </div>
        );
    }

    if (isError || !preferences) {
        return (
            <div className="px-8 py-6">
                <div className="rounded-md border border-red-200 bg-red-50 p-4 text-sm text-red-700">
                    Failed to load preferences.
                </div>
            </div>
        );
    }

    return (
        <div className="flex-1 lg:max-w-4xl space-y-6 p-4 md:p-8 pt-6">
            <div className="space-y-0.5">
                <h2 className="text-2xl font-bold tracking-tight">Account</h2>
                <p className="text-muted-foreground">Manage your account information and preferences.</p>
            </div>
            <Separator className="my-6" />

            <Card className="mb-6">
                <CardHeader>
                    <CardTitle>Change Password</CardTitle>
                    <p className="text-sm text-muted-foreground">Update your password to keep your account secure.</p>
                </CardHeader>
                <CardContent>
                    <form onSubmit={handleChangePassword} className="space-y-4">
                        <div className="space-y-2">
                            <Label htmlFor="old-password">Current Password</Label>
                            <div className="flex items-center gap-2">
                                <Lock className="h-4 w-4 text-muted-foreground" />
                                <Input
                                    id="old-password"
                                    type="password"
                                    placeholder="Enter your current password"
                                    value={oldPassword}
                                    onChange={(e) => setOldPassword(e.target.value)}
                                    className="flex-1"
                                />
                            </div>
                        </div>

                        <Separator />

                        <div className="space-y-2">
                            <Label htmlFor="new-password">New Password</Label>
                            <div className="flex items-center gap-2">
                                <Lock className="h-4 w-4 text-muted-foreground" />
                                <Input
                                    id="new-password"
                                    type="password"
                                    placeholder="Enter your new password"
                                    value={newPassword}
                                    onChange={(e) => setNewPassword(e.target.value)}
                                    className="flex-1"
                                />
                            </div>
                            <p className="text-xs text-muted-foreground">Must be at least 8 characters long</p>
                        </div>

                        <div className="space-y-2">
                            <Label htmlFor="confirm-password">Confirm New Password</Label>
                            <div className="flex items-center gap-2">
                                <Lock className="h-4 w-4 text-muted-foreground" />
                                <Input
                                    id="confirm-password"
                                    type="password"
                                    placeholder="Confirm your new password"
                                    value={confirmPassword}
                                    onChange={(e) => setConfirmPassword(e.target.value)}
                                    className="flex-1"
                                />
                            </div>
                        </div>

                        <div className="flex justify-end pt-4">
                            <Button type="submit" disabled={changePasswordMutation.isPending}>
                                {changePasswordMutation.isPending ? (
                                    <>
                                        <Loader2 className="h-4 w-4 mr-2 animate-spin" />
                                        Changing...
                                    </>
                                ) : (
                                    'Change Password'
                                )}
                            </Button>
                        </div>
                    </form>
                </CardContent>
            </Card>

            {/* Email Change Card */}
            <Card className="mb-6">
                <CardHeader>
                    <CardTitle>Email Address</CardTitle>
                    <p className="text-sm text-muted-foreground">
                        Update your email address. A verification email will be sent to confirm.
                    </p>
                </CardHeader>
                <CardContent>
                    <div className="space-y-4">
                        <div className="space-y-2">
                            <Label>Current Email</Label>
                            <div className="flex items-center gap-2 p-3 rounded-lg border bg-muted/30 text-sm">
                                <Mail className="h-4 w-4 text-muted-foreground flex-shrink-0" />
                                <span className="text-muted-foreground">
                                    {emailData?.email ?? <span className="italic">No email on record</span>}
                                </span>
                            </div>
                        </div>
                        <Separator />
                        <form onSubmit={handleChangeEmail} className="space-y-4">
                            <div className="space-y-2">
                                <Label htmlFor="new-email">New Email Address</Label>
                                <div className="flex items-center gap-2">
                                    <Mail className="h-4 w-4 text-muted-foreground" />
                                    <Input
                                        id="new-email"
                                        type="email"
                                        placeholder="Enter your new email address"
                                        value={newEmail}
                                        onChange={(e) => setNewEmail(e.target.value)}
                                        className="flex-1"
                                        disabled={changeEmailMutation.isPending}
                                    />
                                </div>
                            </div>
                            <div className="space-y-2">
                                <Label htmlFor="email-password">Confirm with Password</Label>
                                <div className="flex items-center gap-2">
                                    <Lock className="h-4 w-4 text-muted-foreground" />
                                    <Input
                                        id="email-password"
                                        type="password"
                                        placeholder="Enter your current password"
                                        value={emailPassword}
                                        onChange={(e) => setEmailPassword(e.target.value)}
                                        className="flex-1"
                                        disabled={changeEmailMutation.isPending}
                                    />
                                </div>
                            </div>
                            <div className="flex justify-end pt-4">
                                <Button type="submit" disabled={changeEmailMutation.isPending}>
                                    {changeEmailMutation.isPending ? (
                                        <>
                                            <Loader2 className="h-4 w-4 mr-2 animate-spin" />
                                            Sending...
                                        </>
                                    ) : (
                                        'Send Verification Email'
                                    )}
                                </Button>
                            </div>
                        </form>
                    </div>
                </CardContent>
            </Card>

            {/* Preferences Card */}
            <Card>
                <CardHeader>
                    <CardTitle>Preferences</CardTitle>
                    <p className="text-sm text-muted-foreground">
                        Customize your account preferences and notification settings.
                    </p>
                </CardHeader>
                <CardContent>
                    <form onSubmit={handleUpdatePreferences} className="space-y-6">
                        <div className="grid gap-6 md:grid-cols-2">
                            <div className="space-y-2">
                                <Label htmlFor="language">Language</Label>
                                <div className="flex items-center gap-2">
                                    <Globe className="h-4 w-4 text-muted-foreground" />
                                    <Select
                                        key={`language-${language}`}
                                        value={language}
                                        onValueChange={(value) => value && setLanguage(value)}
                                    >
                                        <SelectTrigger id="language" className="w-full">
                                            <SelectValue />
                                        </SelectTrigger>
                                        <SelectContent>
                                            {LANGUAGES.map((lang) => (
                                                <SelectItem key={lang.value} value={lang.value}>
                                                    {lang.label}
                                                </SelectItem>
                                            ))}
                                        </SelectContent>
                                    </Select>
                                </div>
                            </div>

                            <div className="space-y-2">
                                <Label htmlFor="theme">Theme</Label>
                                <Select
                                    value={theme}
                                    onValueChange={(value) => setTheme(value as 'light' | 'dark' | 'system')}
                                >
                                    <SelectTrigger id="theme">
                                        <SelectValue />
                                    </SelectTrigger>
                                    <SelectContent>
                                        {THEMES.map((themeOption) => (
                                            <SelectItem key={themeOption.value} value={themeOption.value}>
                                                {themeOption.label}
                                            </SelectItem>
                                        ))}
                                    </SelectContent>
                                </Select>
                            </div>

                            <div className="space-y-2 md:col-span-2">
                                <Label htmlFor="timezone">Timezone</Label>
                                <div className="flex items-center gap-2">
                                    <Clock className="h-4 w-4 text-muted-foreground" />
                                    <Select
                                        key={`timezone-${timezone}`}
                                        value={timezone}
                                        onValueChange={(value) => value && setTimezone(value)}
                                    >
                                        <SelectTrigger id="timezone" className="w-full">
                                            <SelectValue />
                                        </SelectTrigger>
                                        <SelectContent>
                                            {TIMEZONES.map((tz) => (
                                                <SelectItem key={tz.value} value={tz.value}>
                                                    {tz.label}
                                                </SelectItem>
                                            ))}
                                        </SelectContent>
                                    </Select>
                                </div>
                            </div>
                        </div>

                        <Separator />

                        <div className="space-y-4">
                            <h3 className="font-medium">Notifications</h3>
                            <div className="flex items-center justify-between">
                                <div className="space-y-0.5">
                                    <Label htmlFor="email-notifications" className="cursor-pointer">
                                        Email Notifications
                                    </Label>
                                    <p className="text-sm text-muted-foreground">
                                        Receive email notifications for important updates
                                    </p>
                                </div>
                                <Switch
                                    id="email-notifications"
                                    checked={emailNotifications}
                                    onCheckedChange={setEmailNotifications}
                                />
                            </div>
                            <div className="flex items-center justify-between">
                                <div className="space-y-0.5">
                                    <Label htmlFor="in-app-notifications" className="cursor-pointer">
                                        In-App Notifications
                                    </Label>
                                    <p className="text-sm text-muted-foreground">
                                        Show notifications within the application
                                    </p>
                                </div>
                                <Switch
                                    id="in-app-notifications"
                                    checked={inAppNotifications}
                                    onCheckedChange={setInAppNotifications}
                                />
                            </div>
                        </div>

                        <div className="flex justify-end gap-2 pt-4">
                            <Button
                                type="button"
                                variant="outline"
                                onClick={() => {
                                    setLanguage(preferences?.language || 'en');
                                    setTheme((preferences?.theme as 'light' | 'dark' | 'system') || 'system');
                                    setTimezone(preferences?.timezone || 'UTC');
                                    setEmailNotifications(preferences?.email_notifications ?? true);
                                    setInAppNotifications(preferences?.in_app_notifications ?? true);
                                }}
                                disabled={updatePreferencesMutation.isPending}
                            >
                                Reset
                            </Button>
                            <Button type="submit" disabled={updatePreferencesMutation.isPending}>
                                {updatePreferencesMutation.isPending ? (
                                    <>
                                        <Loader2 className="h-4 w-4 mr-2 animate-spin" />
                                        Saving...
                                    </>
                                ) : (
                                    'Save Changes'
                                )}
                            </Button>
                        </div>
                    </form>
                </CardContent>
            </Card>
        </div>
    );
}
