import { useForm, usePage } from '@inertiajs/react';
import { AlignCenter, AlignLeft, AlignRight, 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 { Separator } from '@/components/ui/separator';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Textarea } from '@/components/ui/textarea';
import { update as updateRoute } from '@/routes/appearance';
import type { AuthAppearance } from '@/types/global';

type LoginAppearanceData = Omit<AuthAppearance, 'admin_logo_light' | 'admin_logo_dark' | 'frontend_logo_light' | 'frontend_logo_dark'>;
import { cn } from '@/lib/utils';

type Alignment = 'left' | 'center' | 'right';

// ─── File upload helper ───────────────────────────────────────────────────────

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

    // Read XSRF-TOKEN cookie that Laravel sets on every response
    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;
}

// ─── Image upload field (upload button + URL input + preview) ─────────────────

function ImageUploadField({
    label,
    description,
    value,
    onChange,
    uploadType,
    aspect = 'square',
}: {
    label: string;
    description: string;
    value: string;
    onChange: (url: string) => void;
    uploadType: 'logo' | 'background';
    aspect?: 'square' | 'wide';
}) {
    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>

            {/* Current image preview */}
            {displayValue && (
                <div className="relative w-fit">
                    <img
                        src={displayValue}
                        alt=""
                        className={cn(
                            'rounded-md border object-cover',
                            aspect === 'square' ? 'h-16 w-16' : 'h-20 w-48',
                        )}
                    />
                    {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 row */}
            <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 input */}
            <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/${uploadType === 'logo' ? 'logo.png' : 'background.jpg'}`}
                        value={value}
                        onChange={(e) => onChange(e.target.value)}
                    />
                    {value && (
                        <Button type="button" variant="ghost" size="sm" onClick={handleClear}>
                            Clear
                        </Button>
                    )}
                </div>
            </div>
        </div>
    );
}

// ─── Live preview ─────────────────────────────────────────────────────────────

function AuthPagePreview({ data }: { data: LoginAppearanceData }) {
    const justifyClass: Record<Alignment, string> = {
        left: 'justify-start',
        center: 'justify-center',
        right: 'justify-end',
    };
    const alignClass: Record<Alignment, string> = {
        left: 'items-start',
        center: 'items-center',
        right: 'items-end',
    };

    return (
        <div className="flex flex-col gap-2">
            <p className="text-sm font-medium">Preview</p>
            <div
                className="relative flex h-52 overflow-hidden rounded-lg bg-muted"
                style={
                    data.background_image
                        ? { backgroundImage: `url(${data.background_image})`, backgroundSize: 'cover', backgroundPosition: 'center' }
                        : {}
                }
            >
                <div className={cn('absolute inset-0 flex items-center px-4', justifyClass[data.container_alignment])}>
                    <div className="w-28 space-y-2 rounded-lg bg-white p-4 shadow-md">
                        <div className={cn('flex', data.heading_alignment === 'left' ? 'justify-start' : data.heading_alignment === 'center' ? 'justify-center' : 'justify-end')}>
                            {data.logo_url ? (
                                <img src={data.logo_url} alt="" className="h-4 w-4 rounded object-contain" />
                            ) : (
                                <div className="h-4 w-4 rounded bg-muted-foreground/25" />
                            )}
                        </div>
                        <div className={cn('flex flex-col gap-1', alignClass[data.heading_alignment])}>
                            <div className="h-1.5 w-16 rounded bg-muted-foreground/30" />
                            <div className="h-1 w-10 rounded bg-muted-foreground/20" />
                        </div>
                        <div className="space-y-1">
                            <div className="h-3.5 w-full rounded-sm bg-muted" />
                            <div className="h-3.5 w-full rounded-sm bg-muted" />
                        </div>
                        <div
                            className={cn('h-3.5 w-full rounded-sm', !data.primary_color && 'bg-muted-foreground/30')}
                            style={data.primary_color ? { backgroundColor: data.primary_color } : {}}
                        />
                    </div>
                </div>
            </div>
        </div>
    );
}

// ─── Container alignment picker ───────────────────────────────────────────────

const alignPosition: Record<Alignment, string> = {
    left: 'left-2',
    center: 'left-1/2 -translate-x-1/2',
    right: 'right-2',
};

function ContainerAlignmentPicker({ value, onChange }: { value: Alignment; onChange: (v: Alignment) => void }) {
    return (
        <div className="flex gap-3">
            {(['left', 'center', 'right'] as Alignment[]).map((v) => (
                <button
                    key={v}
                    type="button"
                    onClick={() => onChange(v)}
                    aria-label={`Align ${v}`}
                    className={cn(
                        'relative h-16 w-20 overflow-hidden rounded-md border-2 bg-muted transition-colors',
                        value === v ? 'border-primary' : 'border-border hover:border-muted-foreground/50',
                    )}
                >
                    <div className={cn('absolute top-1/2 h-6 w-6 -translate-y-1/2 rounded bg-background shadow', alignPosition[v])} />
                </button>
            ))}
        </div>
    );
}

// ─── Heading alignment picker ─────────────────────────────────────────────────

const headingIcons = [
    { value: 'left' as Alignment, icon: AlignLeft },
    { value: 'center' as Alignment, icon: AlignCenter },
    { value: 'right' as Alignment, icon: AlignRight },
];

function HeadingAlignmentPicker({ value, onChange }: { value: Alignment; onChange: (v: Alignment) => void }) {
    return (
        <div className="flex gap-2">
            {headingIcons.map(({ value: v, icon: Icon }) => (
                <button
                    key={v}
                    type="button"
                    onClick={() => onChange(v)}
                    aria-label={`Align ${v}`}
                    className={cn(
                        'flex h-9 w-9 items-center justify-center rounded-md border transition-colors',
                        value === v ? 'border-border bg-muted text-foreground' : 'border-transparent text-muted-foreground hover:bg-muted/60',
                    )}
                >
                    <Icon className="h-4 w-4" />
                </button>
            ))}
        </div>
    );
}

// ─── Main component ───────────────────────────────────────────────────────────

export default function LoginAppearanceTabs() {
    const { authAppearance } = usePage().props;

    const { data, setData, patch, processing, recentlySuccessful } = useForm<LoginAppearanceData>({
        logo_url: authAppearance.logo_url,
        background_image: authAppearance.background_image,
        primary_color: authAppearance.primary_color,
        heading_alignment: authAppearance.heading_alignment,
        container_alignment: authAppearance.container_alignment,
        favicon_url: authAppearance.favicon_url,
        custom_css: authAppearance.custom_css,
    });

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

    return (
        <form onSubmit={submit} className="space-y-6">
            <Tabs defaultValue="alignment">
                {/* Tab bar */}
                <div className="border-b">
                    <TabsList
                        variant="line"
                        className="h-auto w-full justify-start gap-0 rounded-none bg-transparent p-0"
                    >
                        {(['logo', 'background', 'colors', 'alignment', 'favicon', 'custom-css'] as const).map((tab) => (
                            <TabsTrigger
                                key={tab}
                                value={tab}
                                className="rounded-none px-4 pb-3 pt-1 capitalize data-active:shadow-none"
                            >
                                {tab === 'custom-css' ? 'Custom CSS' : tab.charAt(0).toUpperCase() + tab.slice(1)}
                            </TabsTrigger>
                        ))}
                    </TabsList>
                </div>

                {/* Two-column layout: controls + preview */}
                <div className="grid grid-cols-1 gap-8 pt-6 lg:grid-cols-[1fr_220px]">
                    <div>
                        {/* ── Logo ── */}
                        <TabsContent value="logo">
                            <ImageUploadField
                                label="Logo"
                                description="Displayed on all auth pages. Square images work best."
                                value={data.logo_url}
                                onChange={(url) => setData('logo_url', url)}
                                uploadType="logo"
                                aspect="square"
                            />
                        </TabsContent>

                        {/* ── Background ── */}
                        <TabsContent value="background">
                            <ImageUploadField
                                label="Background Image"
                                description="Shown in the right panel of the split-screen auth layout."
                                value={data.background_image}
                                onChange={(url) => setData('background_image', url)}
                                uploadType="background"
                                aspect="wide"
                            />
                        </TabsContent>

                        {/* ── Colors ── */}
                        <TabsContent value="colors" className="space-y-4">
                            <div className="space-y-1.5">
                                <Label htmlFor="primary-color">Primary Button Color</Label>
                                <p className="text-xs text-muted-foreground">
                                    Override the default primary color on auth pages.
                                </p>
                                <div className="flex items-center gap-3">
                                    <input
                                        id="primary-color"
                                        type="color"
                                        value={data.primary_color || '#000000'}
                                        onChange={(e) => setData('primary_color', e.target.value)}
                                        className="h-9 w-12 cursor-pointer rounded border border-input bg-transparent p-1"
                                    />
                                    <Input
                                        placeholder="#000000"
                                        value={data.primary_color}
                                        onChange={(e) => setData('primary_color', e.target.value)}
                                        className="w-36 font-mono text-sm"
                                    />
                                    {data.primary_color && (
                                        <Button type="button" variant="ghost" size="sm" onClick={() => setData('primary_color', '')}>
                                            Clear
                                        </Button>
                                    )}
                                </div>
                            </div>
                        </TabsContent>

                        {/* ── Alignment ── */}
                        <TabsContent value="alignment" className="space-y-6">
                            <div className="space-y-3">
                                <Label>Heading Alignment</Label>
                                <HeadingAlignmentPicker
                                    value={data.heading_alignment}
                                    onChange={(v) => setData('heading_alignment', v)}
                                />
                            </div>
                            <Separator />
                            <div className="space-y-3">
                                <Label>Container Alignment</Label>
                                <ContainerAlignmentPicker
                                    value={data.container_alignment}
                                    onChange={(v) => setData('container_alignment', v)}
                                />
                            </div>
                        </TabsContent>

                        {/* ── Favicon ── */}
                        <TabsContent value="favicon" className="space-y-4">
                            <div className="space-y-1.5">
                                <Label htmlFor="favicon-url">Favicon URL</Label>
                                <p className="text-xs text-muted-foreground">
                                    Shown in the browser tab on auth pages. Use a .ico or square PNG.
                                </p>
                                <Input
                                    id="favicon-url"
                                    placeholder="https://example.com/favicon.ico"
                                    value={data.favicon_url}
                                    onChange={(e) => setData('favicon_url', e.target.value)}
                                />
                            </div>
                        </TabsContent>

                        {/* ── Custom CSS ── */}
                        <TabsContent value="custom-css" className="space-y-4">
                            <div className="space-y-1.5">
                                <Label htmlFor="custom-css-input">Custom CSS</Label>
                                <p className="text-xs text-muted-foreground">
                                    Injected into the auth layout. Target{' '}
                                    <code className="rounded bg-muted px-1 py-0.5 text-xs">[data-auth-layout]</code>{' '}
                                    for scoping.
                                </p>
                                <Textarea
                                    id="custom-css-input"
                                    rows={8}
                                    placeholder={`[data-auth-layout] {\n  /* your styles here */\n}`}
                                    value={data.custom_css}
                                    onChange={(e) => setData('custom_css', e.target.value)}
                                    className="font-mono text-xs"
                                />
                            </div>
                        </TabsContent>
                    </div>

                    {/* Preview — always visible */}
                    <AuthPagePreview data={data} />
                </div>
            </Tabs>

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