import { router, useForm, usePage } from '@inertiajs/react';
import { Save } from 'lucide-react';
import { useMemo, useState } from 'react';
import { toast } from 'sonner';
import {
    edit as factoryFormulasEdit,
    store,
    update,
} from '@/actions/App/Http/Controllers/FactoryProductionFormulaController';
import {
    emptyFormulaRecipeLine,
    ProductionFormulaRecipeForm,
} from '@/components/factory/production-formula-recipe-form';
import { ConfirmActionDialog } from '@/components/confirm-action-dialog';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { ProductSearchSelect } from '@/components/ui/product-search-select';
import { formatQuantityForInput } from '@/lib/dates';
import { useLanguage } from '@/contexts/language-context';
import { cn } from '@/lib/utils';

const FIXED_DOUGH_QUANTITY = '1';

const NO_NUMBER_SPINNER =
    '[appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none';

/**
 * @param {object} props
 * @param {'create' | 'edit'} props.mode
 */
export function ProductionFormulaForm({ mode }) {
    const { t } = useLanguage();
    const p = t.productionFormulasPage;
    const a = t.appActions;
    const page = usePage();
    const {
        formula = null,
        products = [],
        rawProducts = [],
        recipeLines = [],
    } = page.props;

    const isCreate = mode === 'create';
    const [confirmOpen, setConfirmOpen] = useState(false);

    const initialLines =
        recipeLines.length > 0
            ? recipeLines.map((line) => ({
                  purchase_product_id: String(line.purchase_product_id ?? ''),
                  quantity: formatQuantityForInput(line.quantity),
                  quantity_unit: line.quantity_unit ?? 'base',
              }))
            : [emptyFormulaRecipeLine()];

    const form = useForm({
        factory_product_id: isCreate ? '' : String(formula?.id ?? ''),
        dough_quantity: FIXED_DOUGH_QUANTITY,
        total_production: isCreate
            ? ''
            : formatQuantityForInput(formula?.total_production ?? ''),
        recipe_lines: initialLines,
    });

    const recipeLabels = useMemo(
        () => ({
            materialsSection: p.materialsSection,
            materialsSectionHint: p.materialsSectionHint,
            addMaterial: p.addMaterial,
            colSerial: p.colSerial,
            colMaterial: p.colMaterial,
            colUnit: p.colUnit,
            removeMaterial: p.removeMaterial,
            rawProductPlaceholder: p.rawProductPlaceholder,
            productSearchPlaceholder: p.productSearchPlaceholder,
            productSearchEmpty: p.productSearchEmpty,
            quantityPlaceholder: p.quantityPlaceholder,
            noProductsHint: p.noProductsHint,
            addProductLink: p.addProductLink,
            baseUnitFallback: p.baseUnitFallback,
        }),
        [p],
    );

    function handleProductChange(productId) {
        if (isCreate) {
            form.setData('factory_product_id', productId);

            return;
        }

        if (String(productId) !== String(formula?.id)) {
            router.get(factoryFormulasEdit.url(productId));
        }
    }

    function handleSubmit(e) {
        e.preventDefault();
        setConfirmOpen(true);
    }

    function commitSave() {
        if (isCreate) {
            form.post(store.url(), {
                onError: () => toast.error(a.requestFailed),
            });

            return;
        }

        form.put(update.url(formula.id), {
            onError: () => toast.error(a.requestFailed),
        });
    }

    return (
        <>
            <ConfirmActionDialog
                open={confirmOpen}
                onOpenChange={setConfirmOpen}
                title={p.confirmSaveTitle}
                description={p.confirmSaveBody}
                confirmLabel={isCreate ? p.createFormula : p.saveFormula}
                cancelLabel={a.cancel}
                processing={form.processing}
                onConfirm={commitSave}
            />

            <form onSubmit={handleSubmit} className="mx-auto w-full max-w-4xl">
            <Card>
                <CardHeader className="pb-4">
                    <CardTitle>{isCreate ? p.createHeadTitle : p.editHeadTitle}</CardTitle>
                </CardHeader>
                <CardContent className="space-y-6">
                    <div className="grid gap-4 sm:grid-cols-3">
                        <div className="space-y-1">
                            <Label htmlFor="dough-quantity">{p.doughQuantityLabel}</Label>
                            <Input
                                id="dough-quantity"
                                type="number"
                                min="0.001"
                                step="0.001"
                                value={FIXED_DOUGH_QUANTITY}
                                disabled
                                className={cn('bg-muted/40', NO_NUMBER_SPINNER)}
                            />
                        </div>

                        <div className="space-y-1">
                            <Label htmlFor="factory-product">{p.productLabel}</Label>
                            {products.length === 0 ? (
                                <p className="text-muted-foreground text-sm">{p.noFactoryProductsHint}</p>
                            ) : (
                                <ProductSearchSelect
                                    id="factory-product"
                                    value={form.data.factory_product_id}
                                    onValueChange={handleProductChange}
                                    products={products}
                                    placeholder={p.factoryProductPlaceholder}
                                    searchPlaceholder={p.productSearchPlaceholder}
                                    emptyLabel={p.productSearchEmpty}
                                    disabled={!isCreate && products.length <= 1}
                                    error={form.errors.factory_product_id}
                                />
                            )}
                            {form.errors.factory_product_id ? (
                                <p className="text-destructive text-sm">
                                    {form.errors.factory_product_id}
                                </p>
                            ) : null}
                        </div>

                        <div className="space-y-1">
                            <Label htmlFor="total-production">{p.totalProductionLabel}</Label>
                            <Input
                                id="total-production"
                                type="number"
                                min="0.001"
                                step="0.001"
                                value={form.data.total_production}
                                onChange={(e) => form.setData('total_production', e.target.value)}
                                aria-invalid={Boolean(form.errors.total_production)}
                                className={cn(
                                    NO_NUMBER_SPINNER,
                                    form.errors.total_production && 'border-destructive',
                                )}
                            />
                            {form.errors.total_production ? (
                                <p className="text-destructive text-sm">{form.errors.total_production}</p>
                            ) : null}
                        </div>
                    </div>

                    <ProductionFormulaRecipeForm
                        lines={form.data.recipe_lines}
                        onLinesChange={(lines) => form.setData('recipe_lines', lines)}
                        rawProducts={rawProducts}
                        errors={form.errors}
                        labels={recipeLabels}
                    />

                    <Button type="submit" disabled={form.processing || (isCreate && products.length === 0)}>
                        <Save className="size-4" />
                        {form.processing
                            ? p.savingFormula
                            : isCreate
                              ? p.createFormula
                              : p.saveFormula}
                    </Button>
                </CardContent>
            </Card>
            </form>
        </>
    );
}
