import type { RequestPayload } from '@inertiajs/core';
import { router, usePage } from '@inertiajs/react';
import {
    Archive,
    ArrowDown,
    ArrowUp,
    CheckCircle2,
    History,
    Package as PackageIcon,
    Plus,
    Trash2,
    X,
} from 'lucide-react';
import { useState } from 'react';
import { CatalogStatusBadge } from '@/components/shared/badges';
import { PageHeader } from '@/components/shared/page-header';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { useCatalogLocale } from '@/hooks/use-catalog-locale';
import { brandLabel, formatPrice, pickLocalizedName } from '@/lib/catalog';
import {
    archive as pricelistArchive,
    exportAll as pricelistsExportAll,
    exportMethod as pricelistExportMethod,
    importMethod as pricelistImportMethod,
    pdf as pricelistPdf,
    publish as pricelistPublish,
} from '@/routes/catalog/pricelists';
import {
    destroy as packageDestroy,
    features as packageFeatures,
    reorder as packageReorder,
    store as packageStore,
    update as packageUpdate,
} from '@/routes/catalog/pricelists/packages';
import { destroy as packageFeatureDestroy } from '@/routes/catalog/pricelists/packages/features';
import type {
    CatalogPricelistImportReport,
    CatalogPricelistShowProps,
} from '@/types/catalog';

/*
 * PCM round 2 — pricelist preview (BR P004/P013). HTML-first rendering of
 * the generated structure: trims → engines × variants price matrix, and the
 * feature structure with P013 display values (● ○ –) per trim.
 */

function PackageManager({
    pricelistId,
    brandCode,
    packages,
    canEdit,
}: {
    pricelistId: number;
    brandCode: string;
    packages: CatalogPricelistShowProps['structure']['packages'];
    canEdit: boolean;
}) {
    const [newName, setNewName] = useState('');
    const [attach, setAttach] = useState<{
        packageId: number;
        q: string;
    } | null>(null);
    const [results, setResults] = useState<{ code: string; name: string }[]>(
        [],
    );

    const post = (url: never, data: RequestPayload, cb?: () => void) =>
        router.post(url, data, { preserveScroll: true, onSuccess: cb });

    const searchFeatures = (value: string) => {
        setAttach((prev) => (prev ? { ...prev, q: value } : prev));

        if (value.trim() === '') {
            setResults([]);

            return;
        }

        fetch(
            `/features/search?brand=${brandCode}&q=${encodeURIComponent(value.trim())}`,
            { headers: { Accept: 'application/json' } },
        )
            .then((response) => response.json())
            .then((data: { features: { code: string; name: string }[] }) =>
                setResults(data.features),
            )
            .catch(() => setResults([]));
    };

    if (!canEdit) {
        return null;
    }

    return (
        <section className="rounded-xl border border-[rgba(30,25,50,0.06)] bg-white shadow-[0_2px_8px_rgba(30,25,50,0.04)]">
            <header className="flex flex-wrap items-center justify-between gap-2 border-b border-gray-100 bg-[#fafafa] px-4 py-2.5">
                <div className="flex items-center gap-2">
                    <PackageIcon size={14} className="text-gray-400" />
                    <h3 className="text-[11px] font-bold tracking-widest text-gray-500 uppercase">
                        Packages
                    </h3>
                </div>
                <div className="flex items-center gap-2">
                    <Input
                        value={newName}
                        onChange={(
                            event: React.ChangeEvent<HTMLInputElement>,
                        ) => setNewName(event.target.value)}
                        className="h-8 w-52 bg-white text-xs"
                        placeholder="Package name (DE)…"
                    />
                    <Button
                        size="sm"
                        disabled={newName.trim() === ''}
                        onClick={() =>
                            post(
                                packageStore({
                                    pricelist: pricelistId,
                                }) as never,
                                { name_de: newName },
                                () => setNewName(''),
                            )
                        }
                    >
                        <Plus size={14} />
                        Add package
                    </Button>
                </div>
            </header>

            <div className="divide-y divide-gray-50">
                {packages.map((pkg) => (
                    <div key={pkg.id} className="px-4 py-3">
                        <div className="flex flex-wrap items-center gap-2">
                            <button
                                type="button"
                                onClick={() =>
                                    post(
                                        packageReorder({
                                            package: pkg.id,
                                        }) as never,
                                        { direction: 'up' },
                                    )
                                }
                                className="flex h-7 w-7 cursor-pointer items-center justify-center rounded-md text-gray-400 hover:bg-slate-100"
                                title="Move up"
                            >
                                <ArrowUp size={13} />
                            </button>
                            <button
                                type="button"
                                onClick={() =>
                                    post(
                                        packageReorder({
                                            package: pkg.id,
                                        }) as never,
                                        { direction: 'down' },
                                    )
                                }
                                className="flex h-7 w-7 cursor-pointer items-center justify-center rounded-md text-gray-400 hover:bg-slate-100"
                                title="Move down"
                            >
                                <ArrowDown size={13} />
                            </button>
                            <Input
                                key={pkg.id}
                                defaultValue={pkg.name.de ?? pkg.code}
                                onBlur={(event) =>
                                    event.target.value !== pkg.name.de &&
                                    post(
                                        packageUpdate({
                                            package: pkg.id,
                                        }) as never,
                                        { name_de: event.target.value },
                                    )
                                }
                                className="h-8 w-64 bg-white text-xs font-semibold text-astara-purple"
                            />
                            <button
                                type="button"
                                onClick={() =>
                                    post(
                                        packageDestroy({
                                            package: pkg.id,
                                        }) as never,
                                        {},
                                    )
                                }
                                className="flex h-7 w-7 cursor-pointer items-center justify-center rounded-md text-gray-300 hover:bg-red-50 hover:text-red-600"
                                title="Delete package"
                            >
                                <Trash2 size={13} />
                            </button>
                        </div>

                        <div className="mt-2 flex flex-wrap items-center gap-1.5">
                            {pkg.feature_codes.map((code) => (
                                <span
                                    key={code}
                                    className="inline-flex h-[18px] items-center gap-1 rounded bg-slate-100 px-1.5 font-mono text-[9px] font-bold text-slate-600"
                                >
                                    {code}
                                    <button
                                        type="button"
                                        onClick={() =>
                                            router.delete(
                                                packageFeatureDestroy({
                                                    package: pkg.id,
                                                    feature_code: code,
                                                }) as never,
                                                { preserveScroll: true },
                                            )
                                        }
                                        className="cursor-pointer text-slate-400 hover:text-red-600"
                                    >
                                        <X size={10} />
                                    </button>
                                </span>
                            ))}

                            {attach?.packageId === pkg.id ? (
                                <div className="relative w-56">
                                    <Input
                                        autoFocus
                                        value={attach.q}
                                        onChange={(
                                            event: React.ChangeEvent<HTMLInputElement>,
                                        ) => searchFeatures(event.target.value)}
                                        className="h-7 bg-white px-2 text-xs"
                                        placeholder="Search feature code…"
                                    />
                                    {results.length > 0 && (
                                        <div className="absolute z-10 mt-1 max-h-40 w-full overflow-y-auto rounded-md border border-gray-100 bg-white shadow-lg">
                                            {results.map((feature) => (
                                                <button
                                                    key={feature.code}
                                                    type="button"
                                                    onClick={() => {
                                                        post(
                                                            packageFeatures({
                                                                package: pkg.id,
                                                            }) as never,
                                                            {
                                                                feature_code:
                                                                    feature.code,
                                                            },
                                                        );
                                                        setAttach(null);
                                                        setResults([]);
                                                    }}
                                                    className="flex w-full cursor-pointer items-center gap-2 px-2 py-1.5 text-left text-[11px] hover:bg-slate-50"
                                                >
                                                    <span className="font-mono text-astara-purple">
                                                        {feature.code}
                                                    </span>
                                                    <span className="truncate text-gray-600">
                                                        {feature.name}
                                                    </span>
                                                </button>
                                            ))}
                                        </div>
                                    )}
                                </div>
                            ) : (
                                <button
                                    type="button"
                                    onClick={() => {
                                        setAttach({ packageId: pkg.id, q: '' });
                                        setResults([]);
                                    }}
                                    className="flex h-[18px] cursor-pointer items-center gap-1 rounded border border-dashed border-gray-300 px-2 text-[9px] font-bold text-gray-500 hover:border-astara-orange hover:text-astara-orange"
                                >
                                    <Plus size={10} />
                                    add feature
                                </button>
                            )}
                        </div>
                    </div>
                ))}
                {packages.length === 0 && (
                    <p className="px-4 py-3 text-[11px] text-gray-400">
                        No packages yet — add the first one to unlock the "P"
                        marker and the package table.
                    </p>
                )}
            </div>
        </section>
    );
}

function ImportReportBox({ report }: { report: CatalogPricelistImportReport }) {
    const totals = (
        ['trims', 'engines', 'variants', 'packages', 'features'] as const
    ).map((key) => report[key]);
    const errorCount = totals.reduce(
        (sum, part) => sum + part.errors.length,
        0,
    );
    const allErrors = totals.flatMap((part) => part.errors);

    return (
        <div
            role="status"
            aria-live="polite"
            className="rounded-xl border border-green-200 bg-green-50/60 px-4 py-3"
        >
            <p className="text-[11px] font-bold text-green-800">
                Import applied — {report.trims.created + report.trims.updated}{' '}
                trims, {report.engines.created + report.engines.updated}{' '}
                engines, {report.variants.created + report.variants.updated}{' '}
                variants, {report.features.created + report.features.updated}{' '}
                features, {report.packages.created + report.packages.updated}{' '}
                packages.
            </p>
            {errorCount > 0 && (
                <ul className="mt-2 list-disc pl-4 text-[10px] text-red-700">
                    {allErrors.slice(0, 20).map((error) => (
                        <li key={error}>{error}</li>
                    ))}
                </ul>
            )}
        </div>
    );
}

export function PricelistShowView({
    pricelist,
    structure,
    versions,
    import_report,
}: CatalogPricelistShowProps) {
    const locale = useCatalogLocale();
    const { props } = usePage();
    const canEdit = props.auth.can.edit_catalog;

    const resolve = (
        names: { de: string | null; fr: string | null; it: string | null },
        fallback: string,
    ) => {
        const picked = pickLocalizedName(
            { name_de: names.de, name_fr: names.fr, name_it: names.it },
            locale,
            names.de ?? names.fr ?? names.it ?? fallback,
        );

        return picked.text;
    };

    return (
        <div className="custom-scroll flex-1 overflow-y-auto">
            <PageHeader
                title={`${brandLabel(pricelist.brand_code)} — ${structure.model.key} (${structure.year})`}
                subtitle={`Body type ${structure.body_type} · Version ${pricelist.version_no}`}
            >
                {canEdit && (
                    <div className="flex items-center gap-2">
                        <Button
                            size="sm"
                            variant="outline"
                            disabled={pricelist.status === 'Draft'}
                            onClick={() =>
                                router.post(
                                    pricelistArchive({
                                        pricelist: pricelist.id,
                                    }) as never,
                                    {},
                                    { preserveScroll: true },
                                )
                            }
                        >
                            <History size={14} />
                            Archive as version
                        </Button>
                        <Button
                            size="sm"
                            onClick={() =>
                                router.post(
                                    pricelistPublish({
                                        pricelist: pricelist.id,
                                    }) as never,
                                    {},
                                    { preserveScroll: true },
                                )
                            }
                        >
                            <CheckCircle2 size={14} />
                            {pricelist.status === 'Current'
                                ? 'Republish'
                                : 'Publish'}
                        </Button>
                    </div>
                )}
            </PageHeader>

            <div className="p-4 md:p-6">
                <div className="mx-auto flex max-w-6xl flex-col gap-6 pb-12">
                    {import_report && (
                        <ImportReportBox report={import_report} />
                    )}

                    {canEdit && (
                        <section className="rounded-xl border border-[rgba(30,25,50,0.06)] bg-white px-4 py-3 shadow-[0_2px_8px_rgba(30,25,50,0.04)]">
                            <div className="flex flex-wrap items-center justify-between gap-3">
                                <div className="flex items-center gap-2">
                                    <label className="text-[10px] font-bold tracking-widest text-gray-500 uppercase">
                                        Excel import (trims / engines / variants
                                        / packages / features + DE/FR/IT)
                                    </label>
                                    <input
                                        type="file"
                                        accept=".xlsx,.xls"
                                        id="pcm-import-file"
                                        className="text-[11px]"
                                    />
                                </div>
                                <div className="flex items-center gap-2">
                                    <Button
                                        size="sm"
                                        variant="outline"
                                        onClick={() => {
                                            const file = (
                                                document.getElementById(
                                                    'pcm-import-file',
                                                ) as HTMLInputElement
                                            )?.files?.[0];

                                            if (!file) {
                                                return;
                                            }

                                            const form = new FormData();
                                            form.append('file', file);
                                            router.post(
                                                pricelistImportMethod({
                                                    pricelist: pricelist.id,
                                                }) as never,
                                                form,
                                                { preserveScroll: true },
                                            );
                                        }}
                                    >
                                        Import Excel
                                    </Button>
                                    <Button
                                        size="sm"
                                        variant="outline"
                                        onClick={() =>
                                            window.open(
                                                pricelistExportMethod({
                                                    pricelist: pricelist.id,
                                                }).url,
                                            )
                                        }
                                    >
                                        Export XLSX
                                    </Button>
                                    <Button
                                        size="sm"
                                        variant="outline"
                                        onClick={() =>
                                            window.open(
                                                pricelistPdf({
                                                    pricelist: pricelist.id,
                                                }).url,
                                            )
                                        }
                                    >
                                        Download PDF
                                    </Button>
                                    <Button
                                        size="sm"
                                        variant="outline"
                                        onClick={() =>
                                            window.open(
                                                pricelistsExportAll().url,
                                            )
                                        }
                                    >
                                        Export all
                                    </Button>
                                </div>
                            </div>
                        </section>
                    )}

                    <div className="flex items-center justify-between rounded-xl border border-[rgba(30,25,50,0.06)] bg-white px-4 py-3 shadow-[0_2px_8px_rgba(30,25,50,0.04)]">
                        <span className="text-[10px] font-bold tracking-widest text-gray-400 uppercase">
                            Lifecycle
                        </span>
                        <CatalogStatusBadge status={pricelist.status} />
                        <span className="text-[10px] text-gray-500">
                            {pricelist.published_at
                                ? `Published ${pricelist.published_at}`
                                : 'Not published yet'}
                        </span>
                    </div>

                    {canEdit && (
                        <PackageManager
                            pricelistId={pricelist.id}
                            brandCode={pricelist.brand_code}
                            packages={structure.packages}
                            canEdit={canEdit}
                        />
                    )}

                    {structure.trims.map((trim) => (
                        <section
                            key={trim.id}
                            className="overflow-hidden rounded-xl border border-[rgba(30,25,50,0.06)] bg-white shadow-[0_2px_8px_rgba(30,25,50,0.04)]"
                        >
                            <header className="flex items-center justify-between border-b border-gray-100 bg-[#fafafa] px-4 py-2.5">
                                <h3 className="text-[11px] font-bold tracking-widest text-astara-purple uppercase">
                                    {trim.name ?? trim.key}
                                </h3>
                                <CatalogStatusBadge status={trim.status} />
                            </header>

                            {trim.engines.length > 0 && (
                                <div className="overflow-x-auto">
                                    <table className="w-full border-collapse text-left">
                                        <thead>
                                            <tr className="border-b border-gray-100 bg-gray-50/50">
                                                <th
                                                    scope="col"
                                                    className="px-4 py-2 text-[9px] font-bold tracking-widest text-gray-400 uppercase"
                                                >
                                                    Engine
                                                </th>
                                                <th
                                                    scope="col"
                                                    className="px-4 py-2 text-right text-[9px] font-bold tracking-widest text-gray-400 uppercase"
                                                >
                                                    Variant
                                                </th>
                                                <th
                                                    scope="col"
                                                    className="px-4 py-2 text-right text-[9px] font-bold tracking-widest text-gray-400 uppercase"
                                                >
                                                    Price (CHF)
                                                </th>
                                            </tr>
                                        </thead>
                                        <tbody>
                                            {trim.engines.flatMap((engine) =>
                                                engine.variants.length === 0
                                                    ? [
                                                          <tr
                                                              key={`${engine.id}-empty`}
                                                              className="border-b border-gray-50"
                                                          >
                                                              <td className="px-4 py-2 font-mono text-[10px] text-gray-500">
                                                                  {engine.key}
                                                              </td>
                                                              <td className="px-4 py-2 text-[10px] text-gray-400 italic">
                                                                  no variant
                                                              </td>
                                                              <td className="px-4 py-2 text-right text-[10px] text-gray-300">
                                                                  –
                                                              </td>
                                                          </tr>,
                                                      ]
                                                    : engine.variants.map(
                                                          (variant) => (
                                                              <tr
                                                                  key={
                                                                      variant.id
                                                                  }
                                                                  className="border-b border-gray-50"
                                                              >
                                                                  <td className="px-4 py-2 font-mono text-[10px] text-gray-500">
                                                                      {
                                                                          engine.key
                                                                      }
                                                                  </td>
                                                                  <td className="px-4 py-2 text-[11px] font-semibold text-astara-purple">
                                                                      {
                                                                          variant.name
                                                                      }
                                                                  </td>
                                                                  <td className="px-4 py-2 text-right text-[11px] tabular-nums">
                                                                      {variant.price ===
                                                                      null ? (
                                                                          <span className="text-gray-300">
                                                                              –
                                                                          </span>
                                                                      ) : (
                                                                          <span className="font-bold text-gray-600">
                                                                              {formatPrice(
                                                                                  variant.price,
                                                                              )}
                                                                          </span>
                                                                      )}
                                                                  </td>
                                                              </tr>
                                                          ),
                                                      ),
                                            )}
                                        </tbody>
                                    </table>
                                </div>
                            )}

                            {trim.categories.map((category) => (
                                <div
                                    key={category.code}
                                    className="border-t border-gray-100"
                                >
                                    <h4 className="px-4 py-2 text-[10px] font-bold tracking-widest text-slate-600 uppercase">
                                        {resolve(category.name, category.code)}
                                    </h4>
                                    <table className="w-full border-collapse">
                                        <tbody>
                                            {category.features.map(
                                                (feature) => (
                                                    <tr
                                                        key={feature.code}
                                                        className="border-t border-gray-50"
                                                    >
                                                        <td className="w-8 px-4 py-1 text-center text-[12px] text-astara-orange">
                                                            {feature.symbol}
                                                        </td>
                                                        <td className="px-2 py-1 text-[11px] text-gray-700">
                                                            {resolve(
                                                                feature.name,
                                                                feature.code,
                                                            )}
                                                            {/* P013: feature is available within a package. */}
                                                            {feature.in_package && (
                                                                <span
                                                                    title="Available in a package"
                                                                    className="ml-1.5 inline-flex h-[13px] items-center rounded bg-purple-50 px-1 align-middle text-[8px] font-bold tracking-wider text-astara-purple uppercase"
                                                                >
                                                                    P
                                                                </span>
                                                            )}
                                                        </td>
                                                        <td className="px-2 py-1 text-right font-mono text-[10px] text-gray-400">
                                                            {feature.code}
                                                        </td>
                                                    </tr>
                                                ),
                                            )}
                                        </tbody>
                                    </table>
                                </div>
                            ))}
                        </section>
                    ))}

                    {structure.packages.length > 0 && (
                        <section className="overflow-hidden rounded-xl border border-[rgba(30,25,50,0.06)] bg-white shadow-[0_2px_8px_rgba(30,25,50,0.04)]">
                            <header className="flex items-center gap-2 border-b border-gray-100 bg-[#fafafa] px-4 py-2.5">
                                <PackageIcon
                                    size={14}
                                    className="text-gray-400"
                                />
                                <h3 className="text-[11px] font-bold tracking-widest text-gray-500 uppercase">
                                    Packages (price table appendix)
                                </h3>
                            </header>
                            <div className="divide-y divide-gray-50">
                                {structure.packages.map((pkg) => (
                                    <div key={pkg.id} className="px-4 py-2.5">
                                        <p className="text-[11px] font-bold text-astara-purple">
                                            {resolve(pkg.name, pkg.code)}
                                        </p>
                                        <p className="mt-0.5 font-mono text-[10px] text-gray-500">
                                            {pkg.feature_codes.length > 0
                                                ? pkg.feature_codes.join(' · ')
                                                : '—'}
                                        </p>
                                    </div>
                                ))}
                            </div>
                        </section>
                    )}

                    {versions.length > 0 && (
                        <section className="rounded-xl border border-[rgba(30,25,50,0.06)] bg-white shadow-[0_2px_8px_rgba(30,25,50,0.04)]">
                            <header className="flex items-center gap-2 border-b border-gray-100 bg-[#fafafa] px-4 py-2.5">
                                <Archive size={14} className="text-gray-400" />
                                <h3 className="text-[11px] font-bold tracking-widest text-gray-500 uppercase">
                                    Version history (P005)
                                </h3>
                            </header>
                            <div className="divide-y divide-gray-50">
                                {[...versions].reverse().map((version) => (
                                    <div
                                        key={version.id}
                                        className="flex items-center justify-between px-4 py-2"
                                    >
                                        <span className="font-mono text-[11px] font-bold text-astara-purple">
                                            v{version.version_no}
                                        </span>
                                        <CatalogStatusBadge
                                            status={version.status}
                                        />
                                        <span className="text-[10px] text-gray-500">
                                            {version.created_at}
                                        </span>
                                    </div>
                                ))}
                            </div>
                        </section>
                    )}
                </div>
            </div>
        </div>
    );
}
