/* The business's own look (owner, in Settings): a colour for buttons and highlights, and a logo. Without a logo,
   the business's initials are shown on its colour. The colour shows straight away as a preview; Save keeps it. */
import { router } from '@inertiajs/react';
import { useEffect, useRef, useState } from 'react';
import { AlertTriangle, ImagePlus, Palette, Save, Trash2 } from 'lucide-react';
import BusinessMark from './BusinessMark';
import { Button, Card, CardHeader, cx } from './ui';

const SWATCHES = ['#2563eb', '#7c3aed', '#4f46e5', '#0891b2', '#059669', '#65a30d', '#ca8a04', '#ea580c', '#dc2626', '#db2777', '#0f172a'];
const DEFAULT = '#2563eb';

/** Too light for white writing on it (buttons have white text). */
function tooLight(hex: string): boolean {
    const n = parseInt(hex.slice(1), 16);
    const [r, g, b] = [(n >> 16) & 255, (n >> 8) & 255, n & 255].map((v) => { const c = v / 255; return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4; });
    return 0.2126 * r + 0.7152 * g + 0.0722 * b > 0.45;
}

export default function BrandingCard({ name, brandColor, logoUrl, initials }: { name: string; brandColor: string; logoUrl: string | null; initials: string }) {
    const saved = brandColor || DEFAULT;
    const [color, setColor] = useState(saved);
    const [logo, setLogo] = useState<{ file: File; url: string } | null>(null);
    const [problem, setProblem] = useState<string | null>(null);
    const [busy, setBusy] = useState(false);
    const input = useRef<HTMLInputElement>(null);

    // preview the colour across the page while choosing; put the saved one back when leaving without saving
    useEffect(() => { document.documentElement.style.setProperty('--brand', color); }, [color]);
    useEffect(() => () => { document.documentElement.style.setProperty('--brand', saved); }, [saved]);
    useEffect(() => () => { if (logo) URL.revokeObjectURL(logo.url); }, [logo]);

    const pick = (file?: File) => {
        if (!file) return;
        if (!/^image\/(png|jpe?g|webp)$/.test(file.type)) return setProblem('Choose a picture (PNG, JPG or WebP).');
        if (file.size > 2 * 1024 * 1024) return setProblem('That picture is too big (2 MB at most).');
        setProblem(null);
        setLogo({ file, url: URL.createObjectURL(file) });
    };
    const saveLogo = () => logo && router.post(route('branding.logo.upload'), { logo: logo.file }, {
        forceFormData: true, preserveScroll: true, onStart: () => setBusy(true), onFinish: () => setBusy(false),
        onSuccess: () => setLogo(null), onError: (e) => setProblem(e.logo ?? 'Could not save that picture.'),
    });

    return (
        <Card>
            <CardHeader icon={Palette} title="Branding" subtitle="Your colour and logo, on your team’s screens." />

            {/* what it looks like */}
            <div className="mt-4 flex items-center gap-3 rounded-xl border border-line bg-white p-3">
                <BusinessMark logoUrl={logo?.url ?? logoUrl} initials={initials} className="!size-10" />
                <span className="min-w-0 flex-1 truncate font-bold text-ink">{name}</span>
                <span className="rounded-lg bg-brand px-3 py-1.5 text-xs font-bold text-white">Button</span>
            </div>

            <p className="mt-4 mb-2 text-sm font-bold text-ink">Colour</p>
            <div className="flex flex-wrap items-center gap-2">
                {SWATCHES.map((c) => (
                    <button key={c} type="button" onClick={() => setColor(c)} aria-label={`Colour ${c}`}
                        className={cx('size-9 rounded-full ring-offset-2 transition', color === c ? 'ring-2 ring-ink' : 'ring-1 ring-line')} style={{ background: c }} />
                ))}
                <label className="relative grid size-9 cursor-pointer place-items-center overflow-hidden rounded-full ring-1 ring-line" title="Any colour">
                    <span className="text-xs font-bold text-muted">+</span>
                    <input type="color" value={color} onChange={(e) => setColor(e.target.value)} className="absolute inset-0 cursor-pointer opacity-0" aria-label="Any colour" />
                </label>
            </div>
            {tooLight(color) && <p className="mt-2 flex items-center gap-1.5 text-xs font-semibold text-amber-700"><AlertTriangle className="size-3.5" aria-hidden />This colour is light: white writing on buttons may be hard to read.</p>}
            <div className="mt-3 flex gap-2">
                <Button type="button" size="sm" icon={Save} disabled={busy || color === saved}
                    onClick={() => router.put(route('branding.update'), { brand_color: color }, { preserveScroll: true, onStart: () => setBusy(true), onFinish: () => setBusy(false) })}>
                    Save colour
                </Button>
                {color !== DEFAULT && <Button type="button" size="sm" variant="ghost" onClick={() => setColor(DEFAULT)}>The app’s blue</Button>}
            </div>

            <p className="mt-5 mb-2 text-sm font-bold text-ink">Logo <span className="font-normal text-muted">(optional)</span></p>
            <p className="mb-2 text-xs text-muted">{logoUrl || logo ? 'Shown at the top of every screen.' : `No logo: your initials (${initials}) are shown on your colour.`}</p>
            <input ref={input} type="file" accept="image/png,image/jpeg,image/webp" className="hidden" onChange={(e) => { pick(e.target.files?.[0]); e.target.value = ''; }} />
            <div className="flex flex-wrap gap-2">
                {logo ? (
                    <>
                        <Button type="button" size="sm" icon={Save} onClick={saveLogo} disabled={busy}>{busy ? 'Saving…' : 'Save logo'}</Button>
                        <Button type="button" size="sm" variant="ghost" onClick={() => setLogo(null)}>Cancel</Button>
                    </>
                ) : (
                    <>
                        <Button type="button" size="sm" variant="secondary" icon={ImagePlus} onClick={() => input.current?.click()}>{logoUrl ? 'Change logo' : 'Add a logo'}</Button>
                        {logoUrl && <Button type="button" size="sm" variant="ghost" icon={Trash2} onClick={() => router.delete(route('branding.logo.remove'), { preserveScroll: true })}>Remove</Button>}
                    </>
                )}
            </div>
            {problem && <p className="mt-2 text-xs font-semibold text-rose-600" role="alert">{problem}</p>}
        </Card>
    );
}
