import React, { useEffect, useState, useMemo } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { v4 } from "uuid";
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from "ikoncomponents";
import ExpenseDataTable from "./expenseDataTable";
import {
    Button,
    Dialog,
    DialogContent,
    DialogFooter,
    DialogHeader,
    DialogTitle,
    Form,
    FormControl,
    FormField,
    FormItem,
    FormLabel,
    FormMessage,
    Input,
    Textarea,
} from "ikoncomponents";
import { CountryDetails } from "@/app/utils/mapping/country";
import { updateProductApi } from "@/app/utils/api/productOfProjectApi";
import { useAppCache } from "@/app/utils/context/AppCacheContext";

// ─── Zod Schema ───────────────────────────────────────────────────────────────
const expenseSchema = z.object({
    expenseName: z.string().min(1, "Expense name is required"),
    location: z.string().min(1, "Location is required"),
    currency: z.string().min(1, "Currency is required"),
    cost: z.number().positive("Cost must be greater than 0"),
    quantity: z.number().positive("Quantity must be greater than 0"),
    description: z.string().optional(),
    totalCost: z.number(),
});

type ExpenseData = z.infer<typeof expenseSchema>;

interface ExpenseModalProps {
    isOpen: boolean;
    onClose: (updatedData?: any) => void;
    productIdentifier: string;
    productData: any;
    setProductData: (data: any) => void;
}

const ExpenseModal: React.FC<ExpenseModalProps> = ({
    isOpen,
    onClose,
    productIdentifier,
    productData,
    setProductData,
}) => {
    const [expenseDetails, setExpenseDetails] = useState<Record<string, ExpenseData>>({});
    const [editingExpenseId, setEditingExpenseId] = useState<string | null>(null);
    const [isLoading, setIsLoading] = useState(false);

    // FX rates come from the shared app-wide cache (year -> currency -> rate).
    // Expenses carry no year, so use the current year's rates, falling back to
    // the most recent year available.
    const { fxRateMap } = useAppCache();
    const fxRates = useMemo<Map<string, number>>(() => {
        if (!fxRateMap || fxRateMap.size === 0) return new Map();
        const years = Array.from(fxRateMap.keys()).sort();
        const currentYear = String(new Date().getFullYear());
        const yearKey = fxRateMap.has(currentYear)
            ? currentYear
            : years[years.length - 1];
        return fxRateMap.get(yearKey) ?? new Map();
    }, [fxRateMap]);

    const form = useForm<ExpenseData>({
        resolver: zodResolver(expenseSchema),
        defaultValues: {
            expenseName: "",
            location: "",
            currency: "USD",
            cost: 0,
            quantity: 0,
            description: "",
            totalCost: 0,
        },
    });

    // Load existing expense details
    useEffect(() => {
        if (!productData || !productData.expenseDetails) return;

        const transformed: Record<string, ExpenseData> = {};
        Object.keys(productData.expenseDetails).forEach((uuid) => {
            const e = productData.expenseDetails[uuid];
            transformed[uuid] = {
                expenseName: e.expenseName || "",
                location: e.location || "",
                currency: e.currency || "USD",
                cost: Number(e.cost) || 0,
                quantity: Number(e.quantity) || 0,
                totalCost: Number(e.totalCost) || 0,
                description: e.remarks || "",
            };
        });

        setExpenseDetails(transformed);
    }, [productData, isOpen]);

    // Auto-calculate totalCost on watch
    useEffect(() => {
        const subscription = form.watch((value) => {
            const { cost, quantity, currency } = value;
            if (cost && quantity && currency) {
                const fx = fxRates.get(currency) || 1;
                const total = Number(cost) * Number(quantity) * fx;
                if (form.getValues("totalCost") !== total) {
                    form.setValue("totalCost", total, { shouldValidate: false });
                }
            }
        });
        return () => subscription.unsubscribe();
    }, [form, fxRates]);

    // ─── Add / Update (Zod validates here via handleSubmit) ───────────────────
    const handleAddOrUpdate = (data: ExpenseData) => {
        const fx = fxRates.get(data.currency) || 1;
        const totalCost = data.cost * data.quantity * fx;
        const expenseId = editingExpenseId || v4();

        setExpenseDetails((prev) => ({
            ...prev,
            [expenseId]: { ...data, totalCost },
        }));

        setEditingExpenseId(null);
        form.reset();
    };

    const handleEdit = (id: string) => {
        const item = expenseDetails[id];
        if (item) {
            form.reset(item);
            setEditingExpenseId(id);
        }
    };

    // ─── Done / Save (No Zod validation, bypasses form submit) ───────────────
    const handleSave = async () => {
        if (!productData) {
            console.error("No productData passed to modal");
            return;
        }

        setIsLoading(true);
        try {
            const transformedExpenseDetails: Record<string, any> = {};
            Object.keys(expenseDetails).forEach((uuid) => {
                transformedExpenseDetails[uuid] = {
                    expenseName: expenseDetails[uuid].expenseName,
                    location: expenseDetails[uuid].location,
                    currency: expenseDetails[uuid].currency,
                    cost: Number(expenseDetails[uuid].cost),
                    quantity: Number(expenseDetails[uuid].quantity),
                    totalCost: Number(expenseDetails[uuid].totalCost),
                    remarks: expenseDetails[uuid].description || "",
                };
            });

            const newProductData = {
                ...productData,
                productIdentifier,
                expenseDetails: transformedExpenseDetails,
            };

            // console.log("Final Payload Before PUT:", newProductData);
            const response = await updateProductApi(newProductData);
            setProductData(newProductData);
            console.log("Backend response pf expense ",response)

            onClose();
        } catch (error) {
            console.error("Error saving expenses:", error);
        } finally {
            setIsLoading(false);
        }
    };

    const expenseArray = Object.keys(expenseDetails).map((uuid) => ({
        uuid,
        ...expenseDetails[uuid],
    }));

    return (
        <Dialog open={isOpen} onOpenChange={(open) => open || onClose()}>
            <DialogContent className="sm:max-w-4xl!">
                <DialogHeader>
                    <DialogTitle>Expense</DialogTitle>
                </DialogHeader>

                <Form {...form}>
                    <form
                        onSubmit={form.handleSubmit(handleAddOrUpdate)}
                        className="grid grid-cols-1 gap-3"
                    >
                        <div className="grid grid-cols-3 gap-3">
                            <FormField
                                control={form.control}
                                name="expenseName"
                                render={({ field }) => (
                                    <FormItem>
                                        <FormLabel>Expense Name*</FormLabel>
                                        <FormControl>
                                            <Input {...field} placeholder="Enter expense name" />
                                        </FormControl>
                                        <FormMessage />
                                    </FormItem>
                                )}
                            />

                            <FormField
                                control={form.control}
                                name="location"
                                render={({ field }) => (
                                    <FormItem>
                                        <FormLabel>Location*</FormLabel>
                                        <FormControl>
                                            <Select onValueChange={field.onChange} value={field.value}>
                                                <SelectTrigger>
                                                    <SelectValue placeholder="Choose location" />
                                                </SelectTrigger>
                                                <SelectContent>
                                                    {CountryDetails.map((option: any) => (
                                                        <SelectItem key={option.code} value={option.name}>
                                                            {option.name}
                                                        </SelectItem>
                                                    ))}
                                                </SelectContent>
                                            </Select>
                                        </FormControl>
                                        <FormMessage />
                                    </FormItem>
                                )}
                            />

                            <FormField
                                control={form.control}
                                name="currency"
                                render={({ field }) => (
                                    <FormItem>
                                        <FormLabel>Currency*</FormLabel>
                                        <FormControl>
                                            <Select onValueChange={field.onChange} value={field.value}>
                                                <SelectTrigger>
                                                    <SelectValue placeholder="Choose currency" />
                                                </SelectTrigger>
                                                <SelectContent>
                                                    {["USD", "GBP", "INR", "QAR", "SAR", "AED"].map((c) => (
                                                        <SelectItem key={c} value={c}>{c}</SelectItem>
                                                    ))}
                                                </SelectContent>
                                            </Select>
                                        </FormControl>
                                        <FormMessage />
                                    </FormItem>
                                )}
                            />
                        </div>

                        <div className="grid grid-cols-3 gap-3">
                            <FormField
                                control={form.control}
                                name="cost"
                                render={({ field }) => (
                                    <FormItem>
                                        <FormLabel>Cost*</FormLabel>
                                        <FormControl>
                                            <Input
                                                type="number"
                                                {...field}
                                                onChange={(e) => field.onChange(e.target.valueAsNumber)}
                                            />
                                        </FormControl>
                                        <FormMessage />
                                    </FormItem>
                                )}
                            />

                            <FormField
                                control={form.control}
                                name="quantity"
                                render={({ field }) => (
                                    <FormItem>
                                        <FormLabel>Quantity*</FormLabel>
                                        <FormControl>
                                            <Input
                                                type="number"
                                                {...field}
                                                onChange={(e) => field.onChange(e.target.valueAsNumber)}
                                            />
                                        </FormControl>
                                        <FormMessage />
                                    </FormItem>
                                )}
                            />

                            <FormField
                                control={form.control}
                                name="totalCost"
                                render={({ field }) => (
                                    <FormItem>
                                        <FormLabel>Total Cost*</FormLabel>
                                        <FormControl>
                                            <Input
                                                disabled
                                                type="number"
                                                {...field}
                                                onChange={(e) => field.onChange(e.target.valueAsNumber)}
                                            />
                                        </FormControl>
                                        <FormMessage />
                                    </FormItem>
                                )}
                            />
                        </div>

                        <FormField
                            control={form.control}
                            name="description"
                            render={({ field }) => (
                                <FormItem>
                                    <FormLabel>Description</FormLabel>
                                    <FormControl>
                                        <Textarea {...field} placeholder="Enter description" />
                                    </FormControl>
                                    <FormMessage />
                                </FormItem>
                            )}
                        />

                        <div className="flex justify-end">
                            <Button type="submit">
                                {editingExpenseId ? "Update" : "Add"}
                            </Button>
                        </div>
                    </form>
                </Form>

                <ExpenseDataTable expenseDetails={expenseArray} onEdit={handleEdit} />

                <DialogFooter>
                    <Button type="button" onClick={handleSave} disabled={isLoading}>
                        {isLoading ? "Saving..." : "Done"}
                    </Button>
                </DialogFooter>
            </DialogContent>
        </Dialog>
    );
};

export default ExpenseModal;