import { useEffect, useRef, useState } from 'react';
import { Link, useForm, useHttp } from '@inertiajs/react';
import { ArrowLeft, ArrowRight, Plus, Trash2, ClipboardList, SlidersHorizontal, Users, DollarSign, X, Loader2, Info } from 'lucide-react';
import AppLayout from '@/Layouts/AppLayout';
import { NativeSelect } from '@/Components/ui/native-select';
import { FloatingField } from '@/Components/Proto/UI/FloatingField';
import { SearchableSelect } from '@/Components/Form/SearchableSelect';
import { useToast } from '@/Components/Toast';

// Server-driven port of Pages/Proto/Projects/Create.jsx (faithful to legacy
// createcompanyprojectchild.php). The proto modelled ONE detail with a flat
// products/competitors list; legacy supports N Details ("Add Project"), each
// Detail owning its OWN Colorindo + competitor lines — restructured here into
// repeatable Detail blocks. Cascades mirror the legacy AJAX chain: Company →
// Division/Industry/CompanyCP/Applications/Projected, Producer ⇄ Product.

// Human labels for the creation origin (?from= / Board "New Project" menu).
const SOURCE_LABELS = { 'visit-plan': 'Visit Plan', 'sample-order': 'Sample Order', lwr: 'LWR', quotation: 'Quotation' };

const QUARTERS = ['Q1', 'Q2', 'Q3', 'Q4'];
const currentYear = new Date().getFullYear();
const currentQuarter = `Q${Math.floor(new Date().getMonth() / 3) + 1}`;

const uid = () => `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
const num = (v) => parseFloat(String(v ?? '').replace(/,/g, '')) || 0;
const money = (n) => (Number(n) || 0).toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
const fmt$ = (n) => '$' + money(n);

// Fresh-line factories. Colorindo/competitor defaults mirror legacy JS
// (PriceType/QtType: Colorindo = 2, Competitor = 1). `_uid` is a client-only
// React-key/identity carrier stripped before submit (see `submit()`).
const newColorindo = () => ({ _uid: uid(), PrincipalID: null, ProductID: null, PriceTypeID: 2, Price: '', QtTypeID: 2, Volume: '', SatuanID: null, Value: 0 });
const newCompetitor = () => ({ _uid: uid(), Supplier: '', PrincipalIDComp: null, PrincipalNameComp: '', ProductIDComp: null, ProductNameComp: '', PriceTypeIDComp: 1, PriceComp: '', QtTypeIDComp: 1, VolumeComp: '', SatuanIDComp: null, ValueComp: 0 });
const newDetail = () => ({
    _uid: uid(), ApplicationID: null, OpportunityGroupID: null,
    TargetPrice: '', TargetVolume: '', TargetValue: 0,
    TargetQuartal: currentQuarter, TargetYear: currentYear, Remark: '',
    colorindo: [newColorindo()], competitor: [],
});

const TI = 'h-8 w-full rounded-md border border-input bg-card px-2.5 text-xs text-foreground outline-none transition-colors placeholder:text-muted-foreground/55 focus:border-primary focus:ring-1 focus:ring-primary disabled:cursor-not-allowed disabled:opacity-60';
const TS = `${TI} appearance-none pr-7`;
// CARD (padded) = summary side-panel; PANEL (banded, zones own their padding) = section cards.
const CARD = 'rounded-2xl border border-border bg-card p-6';
const PANEL = 'rounded-2xl border border-border bg-card shadow-sm';
// Line-item tables — bordered wrapper, flat gray header, tfoot totals row.
const TH = 'whitespace-nowrap border-b border-border/70 bg-secondary/40 px-2.5 py-2.5 text-left text-[10.5px] font-semibold uppercase tracking-wider text-muted-foreground';
const TR = 'border-b border-border/40 align-middle last:border-b-0 [&>td]:px-2 [&>td]:py-2';
const ERR = 'mt-1 text-[11px] font-semibold text-danger-text';
const ADD_BTN = 'inline-flex h-8 items-center gap-1.5 rounded-lg border border-primary/50 bg-accent px-3.5 text-[11px] font-bold text-primary transition-colors hover:bg-primary/10';

// Priority accents mirror Proto/Projects/Create's PRIORITY_COLOR: theme-aware semantic
// tokens (readable in BOTH light and dark), keyed by the master row's PriorityName. The DB's
// own Color/BgColor are a badge scheme (e.g. "Very Important" = white text on red) that, used
// as plain <select> text on the card background, renders white-on-white and vanishes — the
// reported bug. These accents reproduce the proto's colored-text look and never disappear.
const PRIORITY_ACCENT = {
    'Very Important': 'var(--color-danger)',
    Important: 'var(--color-info)',
    High: 'var(--color-warning)',
    Normal: 'var(--color-muted-foreground)',
};
const priorityAccent = (name) => PRIORITY_ACCENT[name] ?? 'var(--color-muted-foreground)';

// Red required marker for table headers.
const Req = () => <span className="text-danger-text"> *</span>;

// Card header band (icon tile + uppercase title + optional count pill / muted hint / right action).
// `tile` re-tints the icon tile so each section keeps its own identity color (pigment chips).
function Band({ icon, title, pill, hint, action, tile = 'bg-accent text-primary' }) {
    return (
        <header className="flex items-center gap-2.5 border-b border-border/40 px-5 py-3.5">
            <span className={`grid size-7 shrink-0 place-items-center rounded-lg ${tile}`} aria-hidden="true">{icon}</span>
            <h2 className="m-0 flex items-center gap-2 text-sm font-bold uppercase tracking-wide text-foreground">
                {title}
                {pill && <span className="rounded-full bg-secondary px-2.5 py-0.5 text-[11px] font-bold normal-case tracking-normal text-muted-foreground tabular-nums">{pill}</span>}
            </h2>
            {hint && <span className="hidden text-[12px] font-medium text-muted-foreground/70 sm:inline">{hint}</span>}
            {action && <div className="ml-auto flex items-center gap-2">{action}</div>}
        </header>
    );
}

// Sub-zone header inside a detail block — mockup-style pigment chip + uppercase label.
function ZoneHead({ chip, title, hint, action }) {
    return (
        <div className="mb-2.5 flex items-center justify-between gap-3">
            <h3 className="m-0 flex items-center gap-2 text-[11.5px] font-bold uppercase tracking-wide text-muted-foreground">
                <span className={`size-2.5 shrink-0 rounded-full shadow-[inset_0_0_0_1px_rgba(0,0,0,0.08)] ${chip}`} aria-hidden="true" />
                <span className="text-foreground">{title}</span>
                {hint && <span className="font-medium normal-case tracking-normal text-muted-foreground">{hint}</span>}
            </h3>
            {action}
        </div>
    );
}

function SumRow({ label, children }) {
    return (
        <div className="flex items-center justify-between gap-3 py-1.5">
            <span className="text-[12px] text-muted-foreground/70">{label}</span>
            <span className="text-[12px] font-medium text-muted-foreground text-right">{children}</span>
        </div>
    );
}

// Colorindo (own-product) line table — Supplier is static text (not submitted);
// Product requires a Producer first and shows the projected-item confirm.
function ColorindoTable({
    detail, di, principals, priceTypes, quantityTypes, satuans, productOptionsByLine,
    errors, onFieldChange, onNumberChange, onSelectPrincipal, onSelectProduct, onRemove,
}) {
    const lines = detail.colorindo;
    const total = lines.reduce((s, l) => s + num(l.Value), 0);

    return (
        <>
            <div className="overflow-x-auto rounded-lg border border-border/70">
                <table className="w-full min-w-[1040px] border-collapse">
                    <thead>
                        <tr>
                            <th className={`${TH} w-9`}>#</th>
                            <th className={TH}>Supplier</th>
                            <th className={TH}>Producer<Req /></th>
                            <th className={TH}>Product<Req /></th>
                            <th className={TH}>Price Type<Req /></th>
                            <th className={`${TH} !text-right`}>Price<Req /></th>
                            <th className={TH}>Qty Type<Req /></th>
                            <th className={`${TH} !text-right`}>Qty<Req /></th>
                            <th className={TH}>Satuan<Req /></th>
                            <th className={`${TH} !text-right`}>Value</th>
                            <th className={`${TH} w-10`}></th>
                        </tr>
                    </thead>
                    <tbody>
                        {lines.map((line, li) => {
                            const base = `details.${di}.colorindo.${li}`;
                            return (
                                <tr key={line._uid} className={TR}>
                                    <td className="text-center text-xs font-bold text-muted-foreground">{li + 1}</td>
                                    <td className="whitespace-nowrap text-xs font-semibold text-foreground">Colorindo Chemtra</td>
                                    <td>
                                        {/* Producer is a FILTER, not a gate (2026-07-27) — "Select producer"
                                            clears it without dropping the current product. */}
                                        <SearchableSelect size="sm" label="Producer" placeholder="Select producer"
                                            options={[{ id: '', name: 'Select producer' }, ...principals.map((p) => ({ id: p.ID, name: p.PrincipalName }))]}
                                            value={line.PrincipalID ?? ''}
                                            onChange={(id) => onSelectPrincipal(detail._uid, line._uid, id)} />
                                        {errors[`${base}.PrincipalID`] && <p className={ERR}>{errors[`${base}.PrincipalID`]}</p>}
                                    </td>
                                    <td>
                                        {/* Product-first (2026-07-27): always enabled, listing every active
                                            product — picking one fills Producer in via principalByBarang
                                            (selectColorindoProduct). */}
                                        <SearchableSelect size="sm" label="Product" placeholder="Select product" limit={100}
                                            options={(productOptionsByLine[line._uid] || []).map((b) => ({ id: b.ID, name: b.NamaBarang }))}
                                            value={line.ProductID ?? ''}
                                            onChange={(id) => onSelectProduct(detail._uid, line._uid, id)} />
                                        {errors[`${base}.ProductID`] && <p className={ERR}>{errors[`${base}.ProductID`]}</p>}
                                    </td>
                                    <td>
                                        <select value={line.PriceTypeID ?? ''} onChange={(e) => onFieldChange(detail._uid, line._uid, 'PriceTypeID', e.target.value ? Number(e.target.value) : null)} className={TS}>
                                            <option value="">Price type</option>
                                            {priceTypes.map((p) => <option key={p.ID} value={p.ID}>{p.PriceTypeName}</option>)}
                                        </select>
                                    </td>
                                    <td>
                                        <div className="relative">
                                            <span className="pointer-events-none absolute left-2 top-1/2 -translate-y-1/2 text-[11px] text-muted-foreground" aria-hidden="true">$</span>
                                            <input type="number" step="any" value={line.Price} onChange={(e) => onNumberChange(detail._uid, line._uid, 'Price', e.target.value)} placeholder="0.00" className={`${TI} pl-5 text-right`} />
                                        </div>
                                        {errors[`${base}.Price`] && <p className={ERR}>{errors[`${base}.Price`]}</p>}
                                    </td>
                                    <td>
                                        <select value={line.QtTypeID ?? ''} onChange={(e) => onFieldChange(detail._uid, line._uid, 'QtTypeID', e.target.value ? Number(e.target.value) : null)} className={TS}>
                                            <option value="">Qty type</option>
                                            {quantityTypes.map((q) => <option key={q.ID} value={q.ID}>{q.QuantityTypeName}</option>)}
                                        </select>
                                    </td>
                                    <td>
                                        <input type="number" step="any" value={line.Volume} onChange={(e) => onNumberChange(detail._uid, line._uid, 'Volume', e.target.value)} placeholder="0" className={`${TI} text-right`} />
                                        {errors[`${base}.Volume`] && <p className={ERR}>{errors[`${base}.Volume`]}</p>}
                                    </td>
                                    <td>
                                        <select value={line.SatuanID ?? ''} onChange={(e) => onFieldChange(detail._uid, line._uid, 'SatuanID', e.target.value ? Number(e.target.value) : null)} className={TS}>
                                            <option value="">Satuan</option>
                                            {satuans.map((s) => <option key={s.ID} value={s.ID}>{s.SatuanName}</option>)}
                                        </select>
                                    </td>
                                    <td className="whitespace-nowrap text-right text-xs font-bold text-foreground tabular-nums">{fmt$(line.Value)}</td>
                                    <td>
                                        <div className="flex items-center justify-end">
                                            <button type="button" onClick={() => onRemove(detail._uid, line._uid)} disabled={lines.length <= 1}
                                                title={lines.length <= 1 ? 'Minimal 1 produk' : 'Hapus'} aria-label="Delete"
                                                className="inline-grid size-7 place-items-center rounded-md text-muted-foreground transition-colors hover:bg-danger/10 hover:text-danger-text disabled:cursor-not-allowed disabled:opacity-30">
                                                <Trash2 className="size-3.5" />
                                            </button>
                                        </div>
                                    </td>
                                </tr>
                            );
                        })}
                    </tbody>
                    <tfoot>
                        <tr>
                            <td colSpan={11} className="border-t border-border/70 bg-secondary/30 px-3 py-2.5">
                                <div className="flex items-center justify-end gap-6 text-[12px] text-muted-foreground">
                                    <span>Total Items <strong className="ml-1 font-bold text-foreground tabular-nums">{lines.length}</strong></span>
                                    <span>Total Value <strong className="ml-1 text-[13px] font-extrabold text-primary tabular-nums">{fmt$(total)}</strong></span>
                                </div>
                            </td>
                        </tr>
                    </tfoot>
                </table>
            </div>
        </>
    );
}

// Competitor line table (optional). Producer/Product each offer a dropdown
// (existing principal/product) OR a free-text fallback shown when no id is
// picked — legacy accepts a competitor's producer/product that isn't in our
// own catalog.
function CompetitorTable({
    detail, di, principals, priceTypes, quantityTypes, satuans, productOptionsByLine,
    errors, onFieldChange, onNumberChange, onSelectPrincipal, onSelectProduct, onRemove, emptyLabel,
}) {
    const lines = detail.competitor;
    const total = lines.reduce((s, l) => s + num(l.ValueComp), 0);

    if (lines.length === 0) {
        return (
            <div className="rounded-lg border border-dashed border-border bg-secondary/30 px-5 py-7 text-center">
                <Users className="mx-auto mb-2 size-6 text-muted-foreground/60" aria-hidden="true" />
                <p className="m-0 text-[13px] font-semibold text-foreground">No competitors added yet</p>
                <p className="m-0 mt-0.5 text-xs text-muted-foreground">{emptyLabel}</p>
            </div>
        );
    }

    return (
        <>
            <div className="overflow-x-auto rounded-lg border border-border/70">
                <table className="w-full min-w-[1120px] border-collapse">
                    <thead>
                        <tr>
                            <th className={`${TH} w-9`}>#</th>
                            <th className={TH}>Supplier</th>
                            <th className={TH}>Producer</th>
                            <th className={TH}>Product</th>
                            <th className={TH}>Price Type</th>
                            <th className={`${TH} !text-right`}>Price</th>
                            <th className={TH}>Qty Type</th>
                            <th className={`${TH} !text-right`}>Qty</th>
                            <th className={TH}>Satuan</th>
                            <th className={`${TH} !text-right`}>Value</th>
                            <th className={`${TH} w-10`}></th>
                        </tr>
                    </thead>
                    <tbody>
                        {lines.map((line, li) => {
                            const opts = productOptionsByLine[line._uid] || [];
                            return (
                                <tr key={line._uid} className={TR}>
                                    <td className="text-center text-xs font-bold text-muted-foreground">{li + 1}</td>
                                    <td><input type="text" value={line.Supplier} maxLength={255} onChange={(e) => onFieldChange(detail._uid, line._uid, 'Supplier', e.target.value)} placeholder="Competitor name" className={TI} /></td>
                                    <td>
                                        <div className="flex flex-col gap-1">
                                            <SearchableSelect size="sm" label="Producer" placeholder="Select / type below" allowCustom
                                                options={[{ id: '', name: 'Clear selection' }, ...principals.map((p) => ({ id: p.ID, name: p.PrincipalName }))]}
                                                value={line.PrincipalIDComp ? line.PrincipalIDComp : (line.PrincipalNameComp ? 'CUSTOM::' + line.PrincipalNameComp : '')}
                                                onChange={(id) => onSelectPrincipal(detail._uid, line._uid, id)} />
                                        </div>
                                    </td>
                                    <td>
                                        <div className="flex flex-col gap-1">
                                            <SearchableSelect size="sm" label="Product" placeholder="Select / type below" limit={100} allowCustom
                                                options={[{ id: '', name: 'Clear selection' }, ...opts.map((b) => ({ id: b.ID, name: b.NamaBarang }))]}
                                                value={line.ProductIDComp ? line.ProductIDComp : (line.ProductNameComp ? 'CUSTOM::' + line.ProductNameComp : '')}
                                                onChange={(id) => onSelectProduct(detail._uid, line._uid, id)} />
                                        </div>
                                    </td>
                                    <td>
                                        <select value={line.PriceTypeIDComp ?? ''} onChange={(e) => onFieldChange(detail._uid, line._uid, 'PriceTypeIDComp', e.target.value ? Number(e.target.value) : null)} className={TS}>
                                            <option value="">Price type</option>
                                            {priceTypes.map((p) => <option key={p.ID} value={p.ID}>{p.PriceTypeName}</option>)}
                                        </select>
                                    </td>
                                    <td>
                                        <div className="relative">
                                            <span className="pointer-events-none absolute left-2 top-1/2 -translate-y-1/2 text-[11px] text-muted-foreground" aria-hidden="true">$</span>
                                            <input type="number" step="any" value={line.PriceComp} onChange={(e) => onNumberChange(detail._uid, line._uid, 'PriceComp', e.target.value)} placeholder="0.00" className={`${TI} pl-5 text-right`} />
                                        </div>
                                    </td>
                                    <td>
                                        <select value={line.QtTypeIDComp ?? ''} onChange={(e) => onFieldChange(detail._uid, line._uid, 'QtTypeIDComp', e.target.value ? Number(e.target.value) : null)} className={TS}>
                                            <option value="">Qty type</option>
                                            {quantityTypes.map((q) => <option key={q.ID} value={q.ID}>{q.QuantityTypeName}</option>)}
                                        </select>
                                    </td>
                                    <td><input type="number" step="any" value={line.VolumeComp} onChange={(e) => onNumberChange(detail._uid, line._uid, 'VolumeComp', e.target.value)} placeholder="0" className={`${TI} text-right`} /></td>
                                    <td>
                                        <select value={line.SatuanIDComp ?? ''} onChange={(e) => onFieldChange(detail._uid, line._uid, 'SatuanIDComp', e.target.value ? Number(e.target.value) : null)} className={TS}>
                                            <option value="">Satuan</option>
                                            {satuans.map((s) => <option key={s.ID} value={s.ID}>{s.SatuanName}</option>)}
                                        </select>
                                    </td>
                                    <td className="whitespace-nowrap text-right text-xs font-bold text-foreground tabular-nums">{fmt$(line.ValueComp)}</td>
                                    <td>
                                        <div className="flex items-center justify-end">
                                            <button type="button" onClick={() => onRemove(detail._uid, line._uid)} aria-label="Delete"
                                                className="inline-grid size-7 place-items-center rounded-md text-muted-foreground transition-colors hover:bg-danger/10 hover:text-danger-text">
                                                <Trash2 className="size-3.5" />
                                            </button>
                                        </div>
                                    </td>
                                </tr>
                            );
                        })}
                    </tbody>
                    <tfoot>
                        <tr>
                            <td colSpan={11} className="border-t border-border/70 bg-secondary/30 px-3 py-2.5">
                                <div className="flex items-center justify-end gap-6 text-[12px] text-muted-foreground">
                                    <span>Total Items <strong className="ml-1 font-bold text-foreground tabular-nums">{lines.length}</strong></span>
                                    <span>Total Value <strong className="ml-1 text-[13px] font-extrabold text-primary tabular-nums">{fmt$(total)}</strong></span>
                                </div>
                            </td>
                        </tr>
                    </tfoot>
                </table>
            </div>
        </>
    );
}

export default function CompanyProjectCreate({
    companies = [], priorities = [], opportunityGroups = [], principals = [],
    priceTypes = [], quantityTypes = [], satuans = [], source = null, sourceStatus = null,
}) {
    const { show: showToast } = useToast();
    const optionsHttp = useHttp({});

    const form = useForm({
        CompanyID: null, DivisionID: null, IndustryID: null, CompanyCP: null, UserIDSales: null,
        ProjectPriority: 3, ProjectTitle: '', ProjectDescription: '', CommentProject: '',
        Source: source, details: [newDetail()],
    });
    const { data, errors, processing } = form;

    const [divisionName, setDivisionName] = useState('');
    const [industryName, setIndustryName] = useState('');
    const [companyCpOptions, setCompanyCpOptions] = useState([]);
    const [applicationOptions, setApplicationOptions] = useState([]);
    const [projected, setProjected] = useState({}); // { productId: "comma,separated,projectIds" }
    const [productOptionsByLine, setProductOptionsByLine] = useState({}); // { lineUid: [{ID,NamaBarang}] }
    const [summaryOpen, setSummaryOpen] = useState(false);
    // Monotonic token so a slow response for a company the user already left can't
    // overwrite a newer selection's cascade results (mirrors SuccessStoryCreate;
    // Quotations Create gates on an always-current company-id ref instead).
    const companyReqRef = useRef(0);

    const companyOptions = companies.map((c) => ({ id: c.id, name: c.name }));
    const selectedPriority = priorities.find((p) => p.ID === data.ProjectPriority);
    const selectedPriorityAccent = priorityAccent(selectedPriority?.PriorityName);

    // Product-first picking (2026-07-27): every Colorindo line starts out able to browse
    // EVERY active product (loadProducts(0), see below) instead of requiring a Producer
    // first — picking a product already calls principalByBarang and back-fills Producer
    // (selectColorindoProduct), this just seeds something to pick from up front. Seed the
    // page's very first line once on mount; addDetail/addLine seed every line they create.
    useEffect(() => {
        const firstUid = form.data.details[0]?.colorindo[0]?._uid;
        if (firstUid) loadAllProducts().then((rows) => setProductOptionsByLine((m) => ({ ...m, [firstUid]: rows })));
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);

    // ── Immutable nested-state helpers (uid-keyed — never index-keyed, so a
    //    stale index after add/remove can't corrupt the wrong detail/line). ──
    const patchDetail = (detailUid, patcher) => {
        form.setData((prev) => ({
            ...prev,
            details: prev.details.map((d) => {
                if (d._uid !== detailUid) return d;
                const patch = typeof patcher === 'function' ? patcher(d) : patcher;
                return { ...d, ...patch };
            }),
        }));
    };
    const patchLine = (detailUid, kind, lineUid, patcher) => {
        patchDetail(detailUid, (d) => ({
            [kind]: d[kind].map((l) => {
                if (l._uid !== lineUid) return l;
                const patch = typeof patcher === 'function' ? patcher(l) : patcher;
                return { ...l, ...patch };
            }),
        }));
    };

    // Seed a fresh Colorindo line with every active product (product-first picking,
    // 2026-07-27) — mirrors the mount-time seed above.
    const seedColorindoProducts = (lineUid) => {
        loadAllProducts().then((rows) => setProductOptionsByLine((m) => ({ ...m, [lineUid]: rows })));
    };

    const addDetail = () => {
        const detail = newDetail();
        form.setData((prev) => ({ ...prev, details: [...prev.details, detail] }));
        seedColorindoProducts(detail.colorindo[0]._uid);
    };
    const removeDetail = (detailUid) => form.setData((prev) => (
        prev.details.length <= 1 ? prev : { ...prev, details: prev.details.filter((d) => d._uid !== detailUid) }
    ));
    const addLine = (detailUid, kind) => {
        const line = kind === 'colorindo' ? newColorindo() : newCompetitor();
        patchDetail(detailUid, (d) => ({ [kind]: [...d[kind], line] }));
        if (kind === 'colorindo') seedColorindoProducts(line._uid);
    };
    const removeLine = (detailUid, kind, lineUid) => patchDetail(detailUid, (d) => (
        (kind === 'colorindo' && d.colorindo.length <= 1) ? {} : { [kind]: d[kind].filter((l) => l._uid !== lineUid) }
    ));

    // Simple (non-calculated) field setters, shared by both line tables.
    const setColorindoField = (detailUid, lineUid, key, value) => patchLine(detailUid, 'colorindo', lineUid, { [key]: value });
    const setCompetitorField = (detailUid, lineUid, key, value) => patchLine(detailUid, 'competitor', lineUid, { [key]: value });

    // Auto-calc: line Value = Price × Volume; kept in the submitted data (not
    // display-only) since the backend expects Value/ValueComp/TargetValue.
    const setColorindoNumber = (detailUid, lineUid, key, value) => patchLine(detailUid, 'colorindo', lineUid, (l) => {
        const merged = { ...l, [key]: value };
        return { [key]: value, Value: num(merged.Price) * num(merged.Volume) };
    });
    const setCompetitorNumber = (detailUid, lineUid, key, value) => patchLine(detailUid, 'competitor', lineUid, (l) => {
        const merged = { ...l, [key]: value };
        return { [key]: value, ValueComp: num(merged.PriceComp) * num(merged.VolumeComp) };
    });
    const setDetailNumber = (detailUid, key, value) => patchDetail(detailUid, (d) => {
        const merged = { ...d, [key]: value };
        return { [key]: value, TargetValue: num(merged.TargetPrice) * num(merged.TargetVolume) };
    });

    // ── Cascades (getbarangfromprincipal / getprincipalfrombarang / … parity) ──
    const loadProducts = async (principalId) => {
        if (!principalId) return [];
        const rows = await optionsHttp.get(route('company-projects.options.products', principalId));
        return rows || [];
    };
    // Product-first picking (2026-07-27): the backend's `{principal}` segment accepts the
    // literal 0 to mean "every active product" — a separate helper because `loadProducts`
    // above deliberately short-circuits on a falsy id for its OTHER callers (Competitor
    // picker), which is untouched by this change.
    const loadAllProducts = async () => {
        const rows = await optionsHttp.get(route('company-projects.options.products', 0));
        return rows || [];
    };

    const onCompanyChange = async (companyId) => {
        const token = ++companyReqRef.current;
        const id = companyId ? Number(companyId) : null;
        form.setData((prev) => ({ ...prev, CompanyID: id, DivisionID: null, IndustryID: null, CompanyCP: null, UserIDSales: null }));
        form.clearErrors('CompanyID', 'DivisionID', 'IndustryID', 'CompanyCP');
        setDivisionName(''); setIndustryName(''); setCompanyCpOptions([]); setApplicationOptions([]); setProjected({});
        if (!id) return;

        const meta = await optionsHttp.get(route('company-projects.options.company-meta', id));
        if (token !== companyReqRef.current) return; // a newer company selection superseded this fetch
        form.setData((prev) => ({
            ...prev,
            DivisionID: meta?.divisionId || null,
            IndustryID: meta?.industryId || null,
            UserIDSales: meta?.userIdSales || null,
        }));
        setDivisionName(meta?.divisionName || '');
        setIndustryName(meta?.industryName || '');

        const [cps, apps, proj] = await Promise.all([
            optionsHttp.get(route('company-projects.options.company-cp', id)),
            meta?.divisionId ? optionsHttp.get(route('company-projects.options.applications', meta.divisionId)) : Promise.resolve([]),
            optionsHttp.get(route('company-projects.options.projected', id)),
        ]);
        if (token !== companyReqRef.current) return; // discard if a newer selection landed while these resolved
        setCompanyCpOptions(cps || []);
        setApplicationOptions(apps || []);
        setProjected(proj || {});
    };

    // Colorindo Producer → Product. Producer is a FILTER, not a gate (2026-07-27):
    // clearing it (id=null) widens the product list back to everything and keeps the
    // current pick — it's still valid. Picking a specific producer still narrows +
    // clears the product like before (this per-row select has no principalId per option
    // to check whether the current pick still matches the new producer).
    const selectColorindoPrincipal = async (detailUid, lineUid, principalId) => {
        const id = principalId ? Number(principalId) : null;
        patchLine(detailUid, 'colorindo', lineUid, { PrincipalID: id, ...(id ? { ProductID: null } : {}) });
        const rows = id ? await loadProducts(id) : await loadAllProducts();
        setProductOptionsByLine((m) => ({ ...m, [lineUid]: rows }));
    };

    // Colorindo Product change — projected-item confirm, then sync Producer back.
    const selectColorindoProduct = async (detailUid, lineUid, productId) => {
        const id = productId ? Number(productId) : null;
        if (id && projected[id] && !window.confirm(`Item has been Projected in Company Project ${projected[id]}, Input again?`)) {
            return;
        }
        patchLine(detailUid, 'colorindo', lineUid, { ProductID: id });
        if (!id) return;
        const res = await optionsHttp.get(route('company-projects.options.principal', id));
        const principalId = res?.principalId ? Number(res.principalId) : null;
        if (!principalId) return;
        patchLine(detailUid, 'colorindo', lineUid, { PrincipalID: principalId });
        const rows = await loadProducts(principalId);
        setProductOptionsByLine((m) => ({ ...m, [lineUid]: rows }));
    };

    // Competitor Producer → Product (dropdown path — free text stays user-typed).
    const selectCompetitorPrincipal = async (detailUid, lineUid, principalId) => {
        let id = null;
        let name = '';
        if (typeof principalId === 'string' && principalId.startsWith('CUSTOM::')) {
            name = principalId.replace('CUSTOM::', '');
        } else if (principalId) {
            id = Number(principalId);
            const p = principals.find((x) => x.ID === id);
            name = p ? p.PrincipalName : '';
        }
        patchLine(detailUid, 'competitor', lineUid, { PrincipalIDComp: id, PrincipalNameComp: name, ProductIDComp: null, ProductNameComp: '' });
        const rows = id ? await loadProducts(id) : [];
        setProductOptionsByLine((m) => ({ ...m, [lineUid]: rows }));
    };

    const selectCompetitorProduct = async (detailUid, lineUid, productId) => {
        let id = null;
        let name = '';
        if (typeof productId === 'string' && productId.startsWith('CUSTOM::')) {
            name = productId.replace('CUSTOM::', '');
        } else if (productId) {
            id = Number(productId);
            const opts = productOptionsByLine[lineUid] || [];
            const b = opts.find((x) => x.ID === id);
            name = b ? b.NamaBarang : '';
        }
        patchLine(detailUid, 'competitor', lineUid, { ProductIDComp: id, ProductNameComp: name });
        if (!id) return;
        const res = await optionsHttp.get(route('company-projects.options.principal', id));
        const principalId = res?.principalId ? Number(res.principalId) : null;
        if (!principalId) return;
        const p = principals.find((x) => x.ID === principalId);
        patchLine(detailUid, 'competitor', lineUid, { PrincipalIDComp: principalId, PrincipalNameComp: p ? p.PrincipalName : '' });
        const rows = await loadProducts(principalId);
        setProductOptionsByLine((m) => ({ ...m, [lineUid]: rows }));
    };

    // ── Totals (Quick Insight panel) ──
    const totals = data.details.reduce((acc, d) => {
        acc.colorindoCount += d.colorindo.length;
        acc.competitorCount += d.competitor.length;
        acc.colorindoValue += d.colorindo.reduce((s, l) => s + num(l.Value), 0);
        acc.competitorValue += d.competitor.reduce((s, l) => s + num(l.ValueComp), 0);
        return acc;
    }, { colorindoCount: 0, competitorCount: 0, colorindoValue: 0, competitorValue: 0 });

    const submit = () => {
        if (!window.confirm('Create Project?')) return;
        form.transform((current) => ({
            ...current,
            details: current.details.map(({ _uid, colorindo, competitor, ...rest }) => ({
                ...rest,
                colorindo: colorindo.map(({ _uid: cu, ...c }) => c),
                competitor: competitor.map(({ _uid: cu, ...c }) => c),
            })),
        }));
        form.post(route('company-projects.store'), {
            onError: () => showToast('Please check the form and try again.', 'error'),
        });
    };

    const dash = (v) => (v === '' || v === null || v === undefined) ? '—' : v;

    // One nested block per Detail inside the "Opportunity Details" section — gray
    // head strip (title + live summary pill + remove) over its fields and its OWN
    // Products & Competitors sub-zones. Plain function call (not a component) so
    // inputs keep focus across re-renders; the first detail renders exactly like
    // any added one.
    const renderDetail = (detail, di) => {
        const base = `details.${di}`;
        const detailValue = detail.colorindo.reduce((s, l) => s + num(l.Value), 0);
        return (
            <section key={detail._uid} className="overflow-hidden rounded-xl border border-border bg-card">
                <header className="flex items-center gap-2.5 border-b border-border/60 bg-secondary/40 px-4 py-2.5">
                    <h3 className="m-0 text-[13px] font-bold text-foreground">Detail {di + 1}</h3>
                    <span className="inline-flex items-center gap-1.5 rounded-full border border-border bg-card px-2.5 py-0.5 text-[11px] text-muted-foreground">
                        <strong className="font-bold text-foreground tabular-nums">{detail.colorindo.length}</strong>
                        product{detail.colorindo.length === 1 ? '' : 's'} ·
                        <strong className="font-bold text-foreground tabular-nums">{fmt$(detailValue)}</strong>
                    </span>
                    {data.details.length > 1 && (
                        <button type="button" onClick={() => removeDetail(detail._uid)} title="Remove detail" aria-label={`Remove detail ${di + 1}`}
                            className="ml-auto inline-grid size-8 place-items-center rounded-lg border border-border bg-card text-muted-foreground transition-colors hover:border-danger/40 hover:bg-danger/10 hover:text-danger-text">
                            <Trash2 className="size-3.5" />
                        </button>
                    )}
                </header>

                <div className="grid grid-cols-1 gap-4 p-4 sm:grid-cols-2 lg:grid-cols-3">
                    <div>
                        <FloatingField as="select" label="Application *" value={detail.ApplicationID ?? ''} disabled={!data.CompanyID}
                            onChange={(e) => patchDetail(detail._uid, { ApplicationID: e.target.value ? Number(e.target.value) : null })}>
                            <option value="">{data.CompanyID ? 'Select Application' : 'Pilih company dulu'}</option>
                            {applicationOptions.map((a) => <option key={a.ID} value={a.ID}>{a.ApplicationName}</option>)}
                        </FloatingField>
                        {errors[`${base}.ApplicationID`] && <p className={ERR}>{errors[`${base}.ApplicationID`]}</p>}
                    </div>
                    <div>
                        <FloatingField as="select" label="Opportunity *" value={detail.OpportunityGroupID ?? ''}
                            onChange={(e) => patchDetail(detail._uid, { OpportunityGroupID: e.target.value ? Number(e.target.value) : null })}>
                            <option value="">Select Opportunity</option>
                            {opportunityGroups.map((o) => <option key={o.ID} value={o.ID}>{o.OpportunityGroupName}</option>)}
                        </FloatingField>
                        {errors[`${base}.OpportunityGroupID`] && <p className={ERR}>{errors[`${base}.OpportunityGroupID`]}</p>}
                    </div>
                    <div className="relative">
                        <div className="flex h-11 items-center gap-2 rounded-lg border border-input bg-card px-2.5 transition-colors focus-within:border-primary focus-within:ring-1 focus-within:ring-primary">
                            <NativeSelect compact value={detail.TargetQuartal} onChange={(e) => patchDetail(detail._uid, { TargetQuartal: e.target.value })} className="min-w-0 flex-1 bg-transparent text-xs text-foreground outline-none">
                                {QUARTERS.map((q) => <option key={q} value={q}>{q}</option>)}
                            </NativeSelect>
                            <input type="number" value={detail.TargetYear} min={currentYear - 1} max={currentYear + 30}
                                onChange={(e) => patchDetail(detail._uid, { TargetYear: e.target.value ? Number(e.target.value) : currentYear })}
                                className="min-w-0 flex-1 bg-transparent text-xs text-foreground outline-none" />
                        </div>
                        <span className="pointer-events-none absolute left-1.5 top-0 -translate-y-1/2 bg-card px-1 text-[9px] font-semibold text-muted-foreground">Target Date</span>
                        {(errors[`${base}.TargetQuartal`] || errors[`${base}.TargetYear`]) && <p className={ERR}>{errors[`${base}.TargetQuartal`] || errors[`${base}.TargetYear`]}</p>}
                    </div>
                    <div>
                        <FloatingField label="Target Price *" type="number" step="any" value={detail.TargetPrice} onChange={(e) => setDetailNumber(detail._uid, 'TargetPrice', e.target.value)} />
                        {errors[`${base}.TargetPrice`] && <p className={ERR}>{errors[`${base}.TargetPrice`]}</p>}
                    </div>
                    <div>
                        <FloatingField label="Target Qty *" type="number" step="any" value={detail.TargetVolume} onChange={(e) => setDetailNumber(detail._uid, 'TargetVolume', e.target.value)} />
                        {errors[`${base}.TargetVolume`] && <p className={ERR}>{errors[`${base}.TargetVolume`]}</p>}
                    </div>
                    <div>
                        <FloatingField label="Target Value (auto)" type="text" readOnly value={fmt$(detail.TargetValue)} />
                    </div>
                    <div className="sm:col-span-2 lg:col-span-3">
                        <FloatingField label="Remark *" type="text" maxLength={255} value={detail.Remark} onChange={(e) => patchDetail(detail._uid, { Remark: e.target.value })} />
                        {errors[`${base}.Remark`] && <p className={ERR}>{errors[`${base}.Remark`]}</p>}
                    </div>
                </div>

                <div className="px-4 pb-4">
                    <ZoneHead chip="bg-primary" title="Products" hint="(Colorindo Chemtra)"
                        action={<button type="button" onClick={() => addLine(detail._uid, 'colorindo')} className={ADD_BTN}><Plus className="size-3.5" /> Add Product</button>} />
                    <div>
                        {errors[`${base}.colorindo`] && <p className={`${ERR} mb-2`}>{errors[`${base}.colorindo`]}</p>}
                        <ColorindoTable
                            detail={detail} di={di} principals={principals} priceTypes={priceTypes} quantityTypes={quantityTypes} satuans={satuans}
                            productOptionsByLine={productOptionsByLine} errors={errors}
                            onFieldChange={setColorindoField} onNumberChange={setColorindoNumber}
                            onSelectPrincipal={selectColorindoPrincipal} onSelectProduct={selectColorindoProduct}
                            onRemove={(du, lu) => removeLine(du, 'colorindo', lu)}
                        />
                    </div>
                </div>

                <div className="px-4 pb-4">
                    <ZoneHead chip="bg-danger/80" title="Competitors" hint="(Optional)"
                        action={<button type="button" onClick={() => addLine(detail._uid, 'competitor')} className={ADD_BTN}><Plus className="size-3.5" /> Add Competitor</button>} />
                    <div>
                        <CompetitorTable
                            detail={detail} di={di} principals={principals} priceTypes={priceTypes} quantityTypes={quantityTypes} satuans={satuans}
                            productOptionsByLine={productOptionsByLine} errors={errors}
                            onFieldChange={setCompetitorField} onNumberChange={setCompetitorNumber}
                            onSelectPrincipal={selectCompetitorPrincipal} onSelectProduct={selectCompetitorProduct}
                            onRemove={(du, lu) => removeLine(du, 'competitor', lu)}
                            emptyLabel="Belum ada data competitor. Klik Add Competitor untuk menambah."
                        />
                    </div>
                </div>
            </section>
        );
    };

    return (
        <section className="flex min-w-0 flex-col gap-6">
            <header className="flex items-start justify-between gap-4">
                <div>
                    <p className="m-0 mb-1.5 flex items-center gap-2 text-xs font-semibold text-muted-foreground">
                        <Link href={route('company-projects.index')} className="text-muted-foreground no-underline hover:text-primary">Projects</Link>
                        <span aria-hidden="true">›</span>
                        <span className="text-primary">Create Company Project</span>
                    </p>
                    <h1 className="m-0 text-2xl font-extrabold leading-[1.2] tracking-tight text-foreground">Create Company Project</h1>
                    <p className="m-0 mt-1 text-[13px] font-medium text-muted-foreground">Add a new project to the pipeline to start planning the business opportunity.</p>
                </div>
                <div className="flex shrink-0 items-center gap-2">
                    <button type="button" onClick={() => setSummaryOpen((v) => !v)}
                        className={`inline-flex h-9 items-center justify-center gap-1.5 rounded-lg border px-4 text-xs font-bold transition-colors ${summaryOpen ? 'border-primary/40 bg-accent text-primary' : 'border-input bg-card text-foreground hover:border-primary hover:text-primary'}`}>
                        <ClipboardList className="size-3.5" /> Summary
                    </button>
                    <button type="button" onClick={() => window.history.back()}
                        className="inline-flex h-9 items-center justify-center gap-1.5 rounded-lg border border-input bg-card px-4 text-xs font-bold text-foreground shadow-sm transition-colors hover:border-primary hover:text-primary">
                        <ArrowLeft className="size-3.5" /> Back
                    </button>
                </div>
            </header>

            {source && (
                <div className="flex items-start gap-2.5 rounded-xl border border-info/30 bg-info/5 px-4 py-3 text-[13px] text-info-text">
                    <Info className="mt-0.5 size-4 shrink-0" aria-hidden="true" />
                    <span>Creating from <strong className="font-bold">{SOURCE_LABELS[source] ?? source}</strong> — new items will start at status <strong className="font-bold">{sourceStatus}</strong>.</span>
                </div>
            )}

            <div className={summaryOpen ? 'grid items-start gap-6 lg:grid-cols-[minmax(0,1fr)_340px]' : 'flex min-w-0 flex-col gap-6'}>
                <div className="flex min-w-0 flex-col gap-6">

                    {/* Project Information — standalone banded card; Detail blocks stack below (never
                        beside, since details/products are repeatable and would outgrow a side column) */}
                    <article className={PANEL}>
                        <Band icon={<ClipboardList className="size-4" />} title="Project Information" />
                        <div className="grid grid-cols-1 gap-4 p-5 sm:grid-cols-2">
                            <div>
                                <SearchableSelect label="Company *" placeholder="Select Company" searchPlaceholder="Search company…" options={companyOptions} value={data.CompanyID} onChange={onCompanyChange} />
                                {errors.CompanyID && <p className={ERR}>{errors.CompanyID}</p>}
                            </div>
                            <div className="grid grid-cols-2 gap-4">
                                <FloatingField label="Division (auto)" type="text" readOnly value={divisionName} />
                                <FloatingField label="Industry (auto)" type="text" readOnly value={industryName} />
                            </div>
                            <div>
                                <FloatingField as="select" label="Company CP *" value={data.CompanyCP ?? ''} disabled={!data.CompanyID}
                                    onChange={(e) => form.setData('CompanyCP', e.target.value ? Number(e.target.value) : null)}>
                                    <option value="">{data.CompanyID ? 'Select CompanyCP' : 'Pilih company dulu'}</option>
                                    {companyCpOptions.map((c) => <option key={c.ID} value={c.ID}>{c.CompanyCPName}</option>)}
                                </FloatingField>
                                {errors.CompanyCP && <p className={ERR}>{errors.CompanyCP}</p>}
                            </div>
                            <div>
                                <FloatingField as="select" label="Project Priority *" value={data.ProjectPriority ?? ''}
                                    onChange={(e) => form.setData('ProjectPriority', Number(e.target.value))}
                                    style={{ color: selectedPriorityAccent, borderLeftColor: selectedPriorityAccent, borderLeftWidth: '3px', fontWeight: 700 }}>
                                    {priorities.map((p) => (
                                        <option key={p.ID} value={p.ID} style={{ color: priorityAccent(p.PriorityName), fontWeight: 700 }}>{p.PriorityName}</option>
                                    ))}
                                </FloatingField>
                                {errors.ProjectPriority && <p className={ERR}>{errors.ProjectPriority}</p>}
                            </div>
                            <div>
                                <FloatingField label="Project Title *" type="text" maxLength={255} value={data.ProjectTitle} onChange={(e) => form.setData('ProjectTitle', e.target.value)} />
                                {errors.ProjectTitle && <p className={ERR}>{errors.ProjectTitle}</p>}
                            </div>
                            <div>
                                <FloatingField label="Project Description *" type="text" maxLength={255} value={data.ProjectDescription} onChange={(e) => form.setData('ProjectDescription', e.target.value)} />
                                {errors.ProjectDescription && <p className={ERR}>{errors.ProjectDescription}</p>}
                            </div>
                            <div className="sm:col-span-2">
                                <FloatingField label="Comment *" type="text" maxLength={255} value={data.CommentProject} onChange={(e) => form.setData('CommentProject', e.target.value)} />
                                {errors.CommentProject && <p className={ERR}>{errors.CommentProject}</p>}
                            </div>
                        </div>
                    </article>

                    {/* Opportunity Details — one section wrapping every detail block; adding a
                        detail appends an identical nested block (page shape never changes) */}
                    <article className={PANEL}>
                        <Band icon={<SlidersHorizontal className="size-4" />} title="Opportunity Details"
                            pill={`${data.details.length} detail${data.details.length === 1 ? '' : 's'}`} />
                        <div className="flex flex-col gap-4 p-5">
                            {data.details.map((detail, di) => renderDetail(detail, di))}
                            {/* Add sits BELOW the last detail — after filling a long block the next
                                action is right where the user already is, no scroll-back-up. */}
                            <button type="button" onClick={addDetail}
                                className="flex h-11 w-full items-center justify-center gap-2 rounded-xl border-2 border-dashed border-border text-[13px] font-bold text-muted-foreground transition-colors hover:border-primary/60 hover:bg-accent/40 hover:text-primary">
                                <Plus className="size-4" /> Add Detail
                            </button>
                        </div>
                    </article>
                </div>

                {/* Summary side panel */}
                {summaryOpen && (
                    <aside className="flex flex-col gap-6 lg:sticky lg:top-4">
                        <article className={CARD}>
                            <div className="mb-3 flex items-center justify-between">
                                <h2 className="m-0 flex items-center gap-2 text-sm font-bold uppercase tracking-wide text-foreground"><ClipboardList className="size-4 text-primary" /> Project Summary</h2>
                                <button type="button" onClick={() => setSummaryOpen(false)} className="inline-grid size-7 place-items-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground" aria-label="Close"><X className="size-4" /></button>
                            </div>
                            <SumRow label="Division">{dash(divisionName)}</SumRow>
                            <SumRow label="Industry">{dash(industryName)}</SumRow>
                            <SumRow label="Company">{dash(companyOptions.find((c) => c.id === data.CompanyID)?.name)}</SumRow>
                            <SumRow label="Company CP">{dash(companyCpOptions.find((c) => c.ID === data.CompanyCP)?.CompanyCPName)}</SumRow>
                            <SumRow label="Priority">{dash(selectedPriority?.PriorityName)}</SumRow>
                            <SumRow label="Project Title">{dash(data.ProjectTitle)}</SumRow>
                        </article>
                        <article className={CARD}>
                            <h2 className="m-0 mb-3 text-sm font-bold uppercase tracking-wide text-foreground">Quick Insight</h2>
                            <SumRow label="Details"><span className="tabular-nums">{data.details.length}</span></SumRow>
                            <SumRow label="Products (Colorindo)"><span className="tabular-nums">{totals.colorindoCount}</span></SumRow>
                            <SumRow label="Competitors"><span className="tabular-nums">{totals.competitorCount}</span></SumRow>
                            <div className="my-1.5 border-t border-border/60" />
                            <div className="flex items-center justify-between gap-3 py-1.5">
                                <span className="text-[12px] font-semibold text-foreground">Total Value (Colorindo)</span>
                                <span className="text-sm font-extrabold text-foreground tabular-nums">{fmt$(totals.colorindoValue)}</span>
                            </div>
                            <div className="mt-2 flex items-center justify-between gap-3 rounded-xl border border-border bg-secondary/50 p-3.5">
                                <div>
                                    <span className="block text-[10px] font-bold uppercase tracking-wide text-muted-foreground">Total Value (Competitor)</span>
                                    <strong className="text-xl font-extrabold text-foreground tabular-nums">{fmt$(totals.competitorValue)}</strong>
                                </div>
                                <span className="grid size-10 shrink-0 place-items-center rounded-full bg-accent text-primary"><DollarSign className="size-5" /></span>
                            </div>
                        </article>
                    </aside>
                )}
            </div>

            {/* Floating save pill — bottom CENTER (DecisionBar grammar: narrow pill, never
                covers the sidebar; summary + buttons only). The page keeps bottom padding
                via the spacer below so content can scroll clear of the pill. */}
            <div aria-hidden="true" className="h-16" />
            <div className="fixed bottom-6 left-1/2 z-40 flex -translate-x-1/2 flex-wrap items-center gap-3 rounded-full border border-border bg-card/95 py-2.5 pl-5 pr-2.5 shadow-modal backdrop-blur">
                <span className="whitespace-nowrap text-[13px] text-muted-foreground">Total value
                    <strong className="ml-2 text-[15px] font-extrabold text-foreground tabular-nums">{fmt$(totals.colorindoValue)}</strong>
                </span>
                <div className="flex items-center gap-2">
                    <button type="button" onClick={() => window.history.back()} disabled={processing}
                        className="inline-flex h-9 items-center justify-center rounded-full border border-input bg-card px-4 text-xs font-bold text-foreground transition-colors hover:border-primary hover:text-primary">
                        Cancel
                    </button>
                    <button type="button" onClick={submit} disabled={processing}
                        className="inline-flex h-9 items-center justify-center gap-1.5 rounded-full bg-linear-to-br from-violet-500 to-primary px-5 text-xs font-bold text-white shadow-sm transition-[filter] hover:brightness-105 disabled:opacity-60">
                        {processing ? <><Loader2 className="size-3.5 animate-spin" /> Saving…</> : <>Create Project <ArrowRight className="size-3.5" /></>}
                    </button>
                </div>
            </div>
        </section>
    );
}

CompanyProjectCreate.layout = [AppLayout];
