import AdminLayout from '@/Layouts/AdminLayout';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { useCurrency } from '@/hooks/useCurrency';
import { api } from '@/lib/api';
import { Head, router } from '@inertiajs/react';
import { ArrowLeft, BarChart3, Layers, Save } from 'lucide-react';
import { useState } from 'react';
import { toast } from 'sonner';
import DetailsCard from './components/DetailsCard';
import LimitsTab from './components/LimitsTab';
import ModulesTab from './components/ModulesTab';
import type {
    LimitKey,
    ModuleGroup,
    PlanForm,
    PlanProp,
} from './components/types';

interface Props {
    plan?: PlanProp;
    modules: ModuleGroup[];
    limitKeys: LimitKey[];
}

export default function PlansForm({ plan, modules, limitKeys }: Props) {
    const isEdit = !!plan;
    const { base } = useCurrency();

    const [form, setForm] = useState<PlanForm>({
        slug: plan?.slug ?? '',
        name: plan?.name ?? '',
        description: plan?.description ?? '',
        price_monthly: String(plan?.price_monthly ?? ''),
        price_yearly: String(plan?.price_yearly ?? ''),
        currency: plan?.currency ?? base.code,
        is_active: plan?.is_active ?? true,
        is_public: plan?.is_public ?? true,
        trial_days: String(plan?.trial_days ?? 0),
        sort_order: String(plan?.sort_order ?? 0),
    });

    const [selectedSlugs, setSelectedSlugs] = useState<Set<string>>(
        new Set(plan?.sub_module_slugs ?? []),
    );

    const [limits, setLimits] = useState<Record<string, string>>(
        Object.fromEntries(
            limitKeys.map((k) => [
                k.key,
                plan?.limits[k.key] != null ? String(plan.limits[k.key]) : '',
            ]),
        ),
    );

    const [errors, setErrors] = useState<Record<string, string>>({});
    const [saving, setSaving] = useState(false);

    const setField = (key: keyof PlanForm, value: string | boolean) =>
        setForm((prev) => ({ ...prev, [key]: value }));

    const toggleSlug = (slug: string) =>
        setSelectedSlugs((prev) => {
            const next = new Set(prev);
            if (next.has(slug)) {
                next.delete(slug);
            } else {
                next.add(slug);
            }
            return next;
        });

    const toggleModule = (group: ModuleGroup) => {
        const nonCore = group.sub_modules.filter((s) => !s.is_core);
        const allSelected = nonCore.every((s) => selectedSlugs.has(s.slug));
        setSelectedSlugs((prev) => {
            const next = new Set(prev);
            nonCore.forEach((s) =>
                allSelected ? next.delete(s.slug) : next.add(s.slug),
            );
            return next;
        });
    };

    const selectAll = () => {
        const all = modules.flatMap((m) =>
            m.sub_modules.filter((s) => !s.is_core).map((s) => s.slug),
        );
        setSelectedSlugs(new Set(all));
    };

    const clearAll = () => setSelectedSlugs(new Set());

    const handleSubmit = async (e: React.FormEvent) => {
        e.preventDefault();
        setErrors({});
        setSaving(true);

        const payload = {
            ...form,
            price_monthly: parseFloat(form.price_monthly) || 0,
            price_yearly: parseFloat(form.price_yearly) || 0,
            trial_days: parseInt(form.trial_days) || 0,
            sort_order: parseInt(form.sort_order) || 0,
            sub_module_slugs: Array.from(selectedSlugs),
            limits: Object.fromEntries(
                Object.entries(limits).map(([k, v]) => [
                    k,
                    v === '' ? null : parseFloat(v),
                ]),
            ),
        };

        try {
            if (isEdit) {
                await api.put(`/admin/plans/${plan!.id}`, payload);
            } else {
                await api.post('/admin/plans', payload);
            }
            toast.success(isEdit ? 'Plan updated' : 'Plan created');
            router.visit('/admin/plans');
        } catch (err) {
            const apiErr = err as {
                errors?: Record<string, string[]>;
                message?: string;
            };
            if (apiErr.errors) {
                const flat: Record<string, string> = {};
                Object.entries(apiErr.errors).forEach(([k, v]) => {
                    flat[k] = Array.isArray(v) ? v[0] : String(v);
                });
                setErrors(flat);
                toast.error('Please fix the errors below.');
            } else {
                toast.error(apiErr.message ?? 'Failed to save plan');
            }
        } finally {
            setSaving(false);
        }
    };

    const totalNonCore = modules.flatMap((m) =>
        m.sub_modules.filter((s) => !s.is_core),
    ).length;
    const selectedCount = [...selectedSlugs].filter(
        (slug) =>
            !modules.flatMap((m) => m.sub_modules).find((s) => s.slug === slug)
                ?.is_core,
    ).length;

    return (
        <AdminLayout
            title={isEdit ? `Edit: ${plan!.name}` : 'New Plan'}
            breadcrumbs={[
                { label: 'Billing' },
                { label: 'Plans', href: '/admin/plans' },
                { label: isEdit ? plan!.name : 'New Plan' },
            ]}
        >
            <Head title={isEdit ? `Edit Plan — ${plan!.name}` : 'New Plan'} />

            <form onSubmit={handleSubmit} className="p-6 lg:p-8">
                <div className="mb-6 flex items-center gap-3">
                    <button
                        type="button"
                        onClick={() => router.visit('/admin/plans')}
                        className="border-border text-muted-foreground hover:bg-muted/40 hover:text-foreground flex h-8 w-8 shrink-0 items-center justify-center rounded-lg border transition-colors"
                    >
                        <ArrowLeft className="h-4 w-4" />
                    </button>
                    <Layers className="text-primary h-5 w-5" />
                    <h1 className="text-foreground text-lg font-bold">
                        {isEdit ? 'Edit Plan' : 'New Plan'}
                    </h1>
                </div>

                <div className="grid grid-cols-1 gap-6 lg:grid-cols-[340px_1fr]">
                    {/* Left: Plan details */}
                    <div className="flex flex-col gap-6">
                        <DetailsCard
                            form={form}
                            setField={setField}
                            errors={errors}
                            isEdit={isEdit}
                            baseCode={base.code}
                        />

                        <button
                            type="submit"
                            disabled={saving}
                            className="pf-btn pf-btn-primary flex w-full items-center justify-center gap-2"
                        >
                            <Save className="h-4 w-4" />
                            {saving
                                ? 'Saving…'
                                : isEdit
                                  ? 'Update Plan'
                                  : 'Create Plan'}
                        </button>
                    </div>

                    {/* Right: Tabs */}
                    <Tabs defaultValue="modules">
                        <TabsList className="mb-4">
                            <TabsTrigger value="modules" className="gap-2">
                                <Layers className="h-3.5 w-3.5" />
                                Modules
                                <span className="bg-primary/10 text-primary rounded-full px-1.5 py-0 text-xs font-semibold">
                                    {selectedCount}/{totalNonCore}
                                </span>
                            </TabsTrigger>
                            <TabsTrigger value="limits" className="gap-2">
                                <BarChart3 className="h-3.5 w-3.5" />
                                Limits
                            </TabsTrigger>
                        </TabsList>

                        <TabsContent value="modules">
                            <ModulesTab
                                modules={modules}
                                selectedSlugs={selectedSlugs}
                                onToggleSlug={toggleSlug}
                                onToggleModule={toggleModule}
                                onSelectAll={selectAll}
                                onClearAll={clearAll}
                            />
                        </TabsContent>

                        <TabsContent value="limits">
                            <LimitsTab
                                limitKeys={limitKeys}
                                limits={limits}
                                onChange={(key, value) =>
                                    setLimits((prev) => ({
                                        ...prev,
                                        [key]: value,
                                    }))
                                }
                            />
                        </TabsContent>
                    </Tabs>
                </div>
            </form>
        </AdminLayout>
    );
}
