import { useForm, usePage } from '@inertiajs/react';
import { ImagePlus, X } from 'lucide-react';
import { useRef, useState } from 'react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { update as updateRoute } from '@/routes/appearance';
import type { AuthAppearance } from '@/types/global';
import { cn } from '@/lib/utils';

type SiteLogosData = Pick<
    AuthAppearance,
    'admin_logo_light' | 'admin_logo_dark' | 'frontend_logo_light' | 'frontend_logo_dark' | 'site_name'
>;

type UploadType = 'admin-logo-light' | 'admin-logo-dark' | 'frontend-logo-light' | 'frontend-logo-dark';

async function uploadImage(file: File, type: UploadType): Promise<string> {
    const formData = new FormData();
    formData.append('file', file);
    formData.append('type', type);

    const xsrf = document.cookie
        .split('; ')
        .find((r) => r.startsWith('XSRF-TOKEN='))
        ?.split('=')[1];

    const res = await fetch('/settings/appearance/upload', {
        method: 'POST',
        headers: xsrf ? { 'X-XSRF-TOKEN': decodeURIComponent(xsrf) } : {},
        body: formData,
    });

    if (!res.ok) throw new Error('Upload failed');
    const json = await res.json();
    return json.url as string;
}

function LogoUploadField({
    label,
    description,
    value,
    onChange,
    uploadType,
    background,
}: {
    label: string;
    description: string;
    value: string;
    onChange: (url: string) => void;
    uploadType: UploadType;
    background?: string;
}) {
    const [uploading, setUploading] = useState(false);
    const [uploadError, setUploadError] = useState('');
    const [previewBlob, setPreviewBlob] = useState('');
    const fileRef = useRef<HTMLInputElement>(null);

    const displayValue = previewBlob || value;

    async function handleFile(file: File) {
        const blob = URL.createObjectURL(file);
        setPreviewBlob(blob);
        setUploadError('');
        setUploading(true);

        try {
            const url = await uploadImage(file, uploadType);
            onChange(url);
            setPreviewBlob('');
        } catch {
            setUploadError('Upload failed. Accepted formats: JPG, PNG, GIF, WebP, SVG (max 4 MB).');
            setPreviewBlob('');
        } finally {
            setUploading(false);
        }
    }

    function handleClear() {
        onChange('');
        setPreviewBlob('');
        setUploadError('');
    }

    return (
        <div className="space-y-3">
            <div>
                <Label>{label}</Label>
                <p className="mt-0.5 text-xs text-muted-foreground">{description}</p>
            </div>

            {/* Preview swatch */}
            <div
                className={cn(
                    'flex h-20 w-full items-center justify-center rounded-lg border',
                    background ?? 'bg-muted',
                )}
            >
                {displayValue ? (
                    <img
                        src={displayValue}
                        alt=""
                        className="max-h-12 max-w-[160px] object-contain"
                    />
                ) : (
                    <span className="text-xs text-muted-foreground">No logo set</span>
                )}
            </div>

            {/* Current image controls */}
            {displayValue && (
                <div className="relative w-fit">
                    <img
                        src={displayValue}
                        alt=""
                        className="h-16 w-16 rounded-md border object-contain"
                    />
                    {uploading && (
                        <div className="absolute inset-0 flex items-center justify-center rounded-md bg-black/50">
                            <span className="text-xs font-medium text-white">Uploading…</span>
                        </div>
                    )}
                    {!uploading && (
                        <button
                            type="button"
                            onClick={handleClear}
                            className="absolute -right-2 -top-2 flex h-5 w-5 items-center justify-center rounded-full bg-destructive text-destructive-foreground shadow"
                        >
                            <X className="h-3 w-3" />
                        </button>
                    )}
                </div>
            )}

            {/* Upload button */}
            <div className="flex items-center gap-2">
                <input
                    ref={fileRef}
                    type="file"
                    accept="image/*,.svg"
                    className="sr-only"
                    onChange={(e) => {
                        const file = e.target.files?.[0];
                        if (file) handleFile(file);
                        e.target.value = '';
                    }}
                />
                <Button
                    type="button"
                    variant="outline"
                    size="sm"
                    onClick={() => fileRef.current?.click()}
                    disabled={uploading}
                >
                    <ImagePlus className="mr-1.5 h-3.5 w-3.5" />
                    {uploading ? 'Uploading…' : 'Upload image'}
                </Button>
            </div>

            {uploadError && <p className="text-xs text-destructive">{uploadError}</p>}

            {/* URL fallback */}
            <div className="space-y-1">
                <Label className="text-xs text-muted-foreground">Or paste a URL</Label>
                <div className="flex gap-2">
                    <Input
                        placeholder="https://example.com/logo.png"
                        value={value}
                        onChange={(e) => onChange(e.target.value)}
                    />
                    {value && (
                        <Button type="button" variant="ghost" size="sm" onClick={handleClear}>
                            Clear
                        </Button>
                    )}
                </div>
            </div>
        </div>
    );
}

export default function SiteLogosTabs() {
    const { authAppearance, name: appName } = usePage().props;

    const { data, setData, patch, processing, recentlySuccessful } = useForm<SiteLogosData>({
        admin_logo_light: authAppearance.admin_logo_light,
        admin_logo_dark: authAppearance.admin_logo_dark,
        frontend_logo_light: authAppearance.frontend_logo_light,
        frontend_logo_dark: authAppearance.frontend_logo_dark,
        site_name: authAppearance.site_name,
    });

    function submit(e: React.FormEvent) {
        e.preventDefault();
        patch(updateRoute().url, { preserveScroll: true });
    }

    return (
        <form onSubmit={submit} className="space-y-6">
            {/* ── Brand Name ── */}
            <div className="space-y-1.5">
                <Label htmlFor="site-name">Brand Name</Label>
                <p className="text-xs text-muted-foreground">
                    Overrides the app name from your environment. Shown in the sidebar and browser tab.
                </p>
                <Input
                    id="site-name"
                    placeholder={appName}
                    value={data.site_name}
                    onChange={(e) => setData('site_name', e.target.value)}
                    className="max-w-sm"
                />
            </div>

            <Tabs defaultValue="admin">
                <div className="border-b">
                    <TabsList
                        variant="line"
                        className="h-auto w-full justify-start gap-0 rounded-none bg-transparent p-0"
                    >
                        <TabsTrigger
                            value="admin"
                            className="rounded-none px-4 pb-3 pt-1 data-active:shadow-none"
                        >
                            Admin Logo
                        </TabsTrigger>
                        <TabsTrigger
                            value="frontend"
                            className="rounded-none px-4 pb-3 pt-1 data-active:shadow-none"
                        >
                            Frontend Logo
                        </TabsTrigger>
                    </TabsList>
                </div>

                <div className="pt-6">
                    {/* ── Admin Logo ── */}
                    <TabsContent value="admin">
                        <div className="grid grid-cols-1 gap-8 sm:grid-cols-2">
                            <LogoUploadField
                                label="Light Mode"
                                description="Shown in the admin sidebar and header when light mode is active."
                                value={data.admin_logo_light}
                                onChange={(url) => setData('admin_logo_light', url)}
                                uploadType="admin-logo-light"
                                background="bg-white border"
                            />
                            <LogoUploadField
                                label="Dark Mode"
                                description="Shown in the admin sidebar and header when dark mode is active."
                                value={data.admin_logo_dark}
                                onChange={(url) => setData('admin_logo_dark', url)}
                                uploadType="admin-logo-dark"
                                background="bg-neutral-900"
                            />
                        </div>
                    </TabsContent>

                    {/* ── Frontend Logo ── */}
                    <TabsContent value="frontend">
                        <div className="grid grid-cols-1 gap-8 sm:grid-cols-2">
                            <LogoUploadField
                                label="Light Mode"
                                description="Shown on the public-facing site when light mode is active."
                                value={data.frontend_logo_light}
                                onChange={(url) => setData('frontend_logo_light', url)}
                                uploadType="frontend-logo-light"
                                background="bg-white border"
                            />
                            <LogoUploadField
                                label="Dark Mode"
                                description="Shown on the public-facing site when dark mode is active."
                                value={data.frontend_logo_dark}
                                onChange={(url) => setData('frontend_logo_dark', url)}
                                uploadType="frontend-logo-dark"
                                background="bg-neutral-900"
                            />
                        </div>
                    </TabsContent>
                </div>
            </Tabs>

            <div className="flex items-center gap-3 border-t pt-4">
                <Button type="submit" disabled={processing}>
                    {processing ? 'Saving…' : 'Save logos'}
                </Button>
                {recentlySuccessful && (
                    <p className="text-sm text-muted-foreground">Saved.</p>
                )}
            </div>
        </form>
    );
}
