import { Button, Checkbox, Field } from '@/Components/ui';
import { csrfHeaders } from '@/admin/settings/types';
import type { LogoWallSection } from '@/marketing/cms-types';
import { Loader2, Trash2, Upload } from 'lucide-react';
import { useRef, useState } from 'react';
import { ItemList, LabeledTextarea, RowTools } from './shared';

type Item = LogoWallSection['items'][number];

type Props = {
    value: LogoWallSection;
    onChange: (next: LogoWallSection) => void;
    errors?: Record<string, string>;
};

function blankItem(): Item {
    return { image: '', alt: '', href: '' };
}

export default function LogoWallEditor({ value, onChange, errors }: Props) {
    const e = errors ?? {};

    return (
        <div className="space-y-4">
            <LabeledTextarea
                id={`${value.id}-label`}
                label="Label"
                value={value.label ?? ''}
                onChange={(v) => onChange({ ...value, label: v })}
                error={e.label}
                rows={1}
                placeholder="Powering teams at"
                hint="Short caption beside the logos. Leave blank to hide the label cell."
            />

            <div>
                <p className="mb-2 text-[11px] font-medium text-foreground">Logos</p>
                <p className="mb-3 text-[12px] text-muted-foreground">
                    Section auto-hides when the list is empty (avoids shipping placeholder customer logos).
                </p>
                <ItemList<Item>
                    items={value.items}
                    onChange={(items) => onChange({ ...value, items })}
                    blank={blankItem}
                    addLabel="Add logo"
                    emptyLabel="No logos yet."
                    confirmDelete={(it) => `Delete logo "${it.alt?.trim() || 'unnamed'}"?`}
                    renderRow={(item, idx, h) => {
                        const itemErr = (k: string) => e[`items.${idx}.${k}`];
                        return (
                            <div
                                key={`${value.id}-logo-${idx}`}
                                className="rounded-lg border border-border bg-background/40 p-3"
                            >
                                <div className="flex justify-end">
                                    <RowTools
                                        idx={idx}
                                        count={value.items.length}
                                        onMove={h.move}
                                        onRemove={h.remove}
                                        moveLabel="logo"
                                        removeLabel="logo"
                                    />
                                </div>
                                <div className="mt-2 space-y-3">
                                    <LogoUpload
                                        idPrefix={`${value.id}-logo-${idx}`}
                                        image={item.image}
                                        imageUrl={item.imageUrl}
                                        onChange={(image, imageUrl) =>
                                            h.update({ image, imageUrl })
                                        }
                                        error={itemErr('image')}
                                    />
                                    <div className="grid gap-3 sm:grid-cols-2">
                                        <Field
                                            id={`${value.id}-logo-${idx}-alt`}
                                            label="Alt text"
                                            value={item.alt ?? ''}
                                            onChange={(ev) => h.update({ alt: ev.target.value })}
                                            error={itemErr('alt')}
                                            placeholder="Acme Inc."
                                        />
                                        <Field
                                            id={`${value.id}-logo-${idx}-href`}
                                            label="Link (optional)"
                                            value={item.href ?? ''}
                                            onChange={(ev) => h.update({ href: ev.target.value })}
                                            error={itemErr('href')}
                                            placeholder="https://acme.com"
                                        />
                                    </div>
                                    <label className="flex items-center gap-2 text-[12px] text-muted-foreground">
                                        <Checkbox
                                            checked={Boolean(item.external)}
                                            onChange={(ev) => h.update({ external: ev.target.checked })}
                                        />
                                        Open link in a new tab
                                    </label>
                                </div>
                            </div>
                        );
                    }}
                />
            </div>
        </div>
    );
}

/* Logo upload widget — mirrors TestimonialsEditor's AvatarUpload but
 * tuned for wide logo marks (rectangular preview, no rounded crop).
 * Reuses the shared /admin/marketing/hero-image endpoint (same
 * MediaStorage pipeline + 5 MB cap), same as the atomic ImageBlock.
 * Server returns `{ path, url }`; we store the storage path as `image`
 * plus the resolved `imageUrl` for instant preview. A "Use a URL
 * instead" toggle keeps the public-asset / external-URL path working
 * (any first-party `/path.png` or absolute `https://…` URL). */
function LogoUpload({
    idPrefix,
    image,
    imageUrl,
    onChange,
    error,
}: {
    idPrefix: string;
    image?: string;
    imageUrl?: string;
    onChange: (image: string | undefined, imageUrl: string | undefined) => void;
    error?: string;
}) {
    const fileInputRef = useRef<HTMLInputElement | null>(null);
    const [uploading, setUploading] = useState(false);
    const [uploadError, setUploadError] = useState<string | null>(null);
    const [urlMode, setUrlMode] = useState(false);

    const previewSrc = imageUrl || image || '';
    const hasLogo = previewSrc !== '';

    const onPickFile = async (file: File) => {
        setUploading(true);
        setUploadError(null);
        try {
            const fd = new FormData();
            fd.append('file', file);
            const headers = csrfHeaders();
            delete (headers as Record<string, string>)['Content-Type'];
            const res = await fetch('/admin/marketing/hero-image', {
                method: 'POST',
                credentials: 'same-origin',
                headers,
                body: fd,
            });
            if (res.status === 422) {
                const body = await res.json().catch(() => null);
                setUploadError(body?.errors?.file?.[0] ?? body?.message ?? 'Upload failed (validation).');
                return;
            }
            if (!res.ok) {
                setUploadError(`Upload failed (${res.status}).`);
                return;
            }
            const body = (await res.json()) as { path: string; url: string };
            onChange(body.path, body.url);
        } catch {
            setUploadError('Network error during upload.');
        } finally {
            setUploading(false);
            if (fileInputRef.current) fileInputRef.current.value = '';
        }
    };

    const clear = () => onChange(undefined, undefined);

    return (
        <div className="space-y-1.5">
            <label className="block text-[11px] font-medium text-foreground">Logo</label>
            <div className="flex items-start gap-3 rounded-lg border border-border bg-background p-3">
                {hasLogo ? (
                    <img
                        src={previewSrc}
                        alt=""
                        className="h-12 w-24 shrink-0 rounded border border-border bg-card object-contain p-1"
                    />
                ) : (
                    <div className="flex h-12 w-24 shrink-0 items-center justify-center rounded border border-dashed border-border bg-muted/40 text-[10px] font-medium uppercase tracking-wide text-muted-foreground">
                        none
                    </div>
                )}
                <div className="flex flex-1 flex-col gap-2">
                    <div className="flex flex-wrap items-center gap-2">
                        <Button
                            type="button"
                            variant="secondary"
                            size="sm"
                            onClick={() => fileInputRef.current?.click()}
                            disabled={uploading}
                            data-testid={`${idPrefix}-logo-upload`}
                        >
                            {uploading ? (
                                <Loader2 className="h-3.5 w-3.5 animate-spin" />
                            ) : (
                                <Upload className="h-3.5 w-3.5" />
                            )}
                            {uploading ? 'Uploading…' : hasLogo ? 'Replace' : 'Upload image'}
                        </Button>
                        {hasLogo && (
                            <Button
                                type="button"
                                variant="secondary"
                                size="sm"
                                onClick={clear}
                                disabled={uploading}
                                data-testid={`${idPrefix}-logo-remove`}
                            >
                                <Trash2 className="h-3.5 w-3.5" />
                                Remove
                            </Button>
                        )}
                        <button
                            type="button"
                            onClick={() => setUrlMode((v) => !v)}
                            className="text-[11px] font-medium text-muted-foreground hover:text-accent"
                        >
                            {urlMode ? 'Hide URL field' : 'Use a URL instead'}
                        </button>
                    </div>
                    {urlMode && (
                        <Field
                            id={`${idPrefix}-logo-url`}
                            label=""
                            value={image ?? ''}
                            onChange={(ev) => onChange(ev.target.value || undefined, undefined)}
                            placeholder="https://yoursite.com/logo.png"
                            hint="External URL or /public path. Use Upload above for files you want stored on the active disk."
                        />
                    )}
                </div>
                <input
                    ref={fileInputRef}
                    type="file"
                    accept="image/jpeg,image/png,image/webp"
                    className="hidden"
                    onChange={(ev) => {
                        const f = ev.target.files?.[0];
                        if (f) onPickFile(f);
                    }}
                />
            </div>
            {uploadError && (
                <p className="text-xs text-destructive" role="alert">{uploadError}</p>
            )}
            {error && !uploadError && <p className="text-xs text-destructive">{error}</p>}
        </div>
    );
}
