import { Form, Head } from '@inertiajs/react';
import ConstantsController from '@/actions/App/Http/Controllers/Admin/ConstantsController';
import Heading from '@/components/heading';
import InputError from '@/components/input-error';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { edit as editConstants } from '@/routes/admin/constants';

type Constants = Record<string, unknown>;

type FieldProps = {
    value: unknown;
    path: string[];
    errors: Record<string, string>;
};

function labelFor(key: string): string {
    return key
        .replaceAll('_', ' ')
        .replace(/([a-z])([A-Z])/g, '$1 $2')
        .replace(/\b\w/g, (character) => character.toUpperCase());
}

function fieldName(path: string[], isArrayItem = false): string {
    const [first, ...rest] = path;
    const name = rest.reduce((result, part) => `${result}[${part}]`, first);

    return isArrayItem ? `${name}[]` : name;
}

function errorKey(path: string[]): string {
    return path.join('.');
}

function SettingField({ value, path, errors }: FieldProps) {
    const key = path.at(-1) ?? '';
    const name = fieldName(path);
    const error = errors[errorKey(path)];

    if (Array.isArray(value)) {
        return (
            <div className="grid gap-2">
                <Label>{labelFor(key)}</Label>
                <div className="grid gap-2 sm:grid-cols-3">
                    {value.map((item, index) => (
                        <Input
                            key={`${name}-${index}`}
                            name={fieldName(path, true)}
                            type="number"
                            defaultValue={String(item)}
                            min="1"
                        />
                    ))}
                </div>
                <InputError message={error} />
            </div>
        );
    }

    if (typeof value === 'object' && value !== null) {
        return (
            <div className="grid gap-4 rounded-lg border p-4">
                <h3 className="font-medium">{labelFor(key)}</h3>
                {Object.entries(value as Record<string, unknown>).map(
                    ([childKey, childValue]) => (
                        <SettingField
                            key={`${name}.${childKey}`}
                            value={childValue}
                            path={[...path, childKey]}
                            errors={errors}
                        />
                    ),
                )}
            </div>
        );
    }

    if (typeof value === 'boolean') {
        return (
            <>
                <input name={name} type="hidden" value="0" />
                <label className="flex items-center gap-3">
                    <input
                        name={name}
                        type="checkbox"
                        value="1"
                        defaultChecked={value}
                        className="size-4 rounded border-input"
                    />
                    <span className="text-sm font-medium">{labelFor(key)}</span>
                </label>
            </>
        );
    }

    return (
        <div className="grid gap-2">
            <Label htmlFor={name}>{labelFor(key)}</Label>
            <Input
                id={name}
                name={name}
                type={typeof value === 'number' ? 'number' : 'text'}
                step={typeof value === 'number' ? '0.01' : undefined}
                defaultValue={String(value ?? '')}
            />
            <InputError message={error} />
        </div>
    );
}

export default function ConstantsPage({ constants }: { constants: Constants }) {
    return (
        <>
            <Head title="Application Constants" />

            <div className="space-y-6">
                <Heading
                    variant="small"
                    title="Application Constants"
                    description="Manage dashboard content, feature flags, and growth-score rules."
                />

                <Form
                    {...ConstantsController.update.form()}
                    options={{ preserveScroll: true }}
                    className="space-y-6"
                >
                    {({ processing, errors }) => (
                        <>
                            {(['content', 'feature_flags', 'rules'] as const).map((group) => (
                                <Card key={group}>
                                    <CardHeader>
                                        <CardTitle>{labelFor(group)}</CardTitle>
                                        <CardDescription>
                                            {group === 'content'
                                                ? 'Text displayed throughout the product.'
                                                : group === 'feature_flags'
                                                  ? 'Turn product capabilities on or off.'
                                                  : 'Scoring and recommendation calculations.'}
                                        </CardDescription>
                                    </CardHeader>
                                    <CardContent className="grid gap-4">
                                        {Object.entries(
                                            (constants[group] ?? {}) as Record<string, unknown>,
                                        ).map(([key, value]) => (
                                            <SettingField
                                                key={`${group}.${key}`}
                                                value={value}
                                                path={[`constants`, group, key]}
                                                errors={errors}
                                            />
                                        ))}
                                    </CardContent>
                                </Card>
                            ))}

                            <Button type="submit" disabled={processing}>
                                {processing ? 'Saving…' : 'Save constants'}
                            </Button>
                        </>
                    )}
                </Form>
            </div>
        </>
    );
}

ConstantsPage.layout = {
    breadcrumbs: [
        {
            title: 'Application Constants',
            href: editConstants(),
        },
    ],
};
