import { useFormik } from "formik";
import * as Yup from "yup";
import Modal from "../../components/Modals";
import Datepicker from "../../components/Datepicker";
import IconMail from "../../components/Icon/IconMail";
import IconPhone from "../../components/Icon/IconPhone";
import IconPlus from "../../components/Icon/IconPlus";
import IconX from "../../components/Icon/IconX";
import Button from "../../components/Buttons";
import React, { useState, useMemo } from "react";
import IconCashBanknotes from "../../components/Icon/IconCashBanknotes";
import api from '../../api/axios';
import { toast } from 'react-toastify';

interface Props {
    open: boolean;
    onClose: () => void;
    onSave: (data: any) => void;
    data: any;
}

interface Installment {
    date?: Date;
    amount: number;
}

interface FormValues {
    installments: Installment[];
}

const FeeSchedule = ({ open, onClose, onSave, data }: Props) => {
    const student = data;
    const [loading, setLoading] = useState(false);

    // Convert to number safely
    const balanceAmount = Number(student?.balance_amount || student?.balanceAmount || 0);
    const totalFees = Number(student?.total_fees || student?.totalFee || 0);
    const paidAmount = totalFees - balanceAmount;

    // ==========================================
    // FORMIK - MUST BE FIRST before any function that uses it
    // ==========================================
    const formik = useFormik<FormValues>({
        enableReinitialize: true,
        initialValues: {
            installments: [] as Installment[],
        },
        validationSchema: Yup.object({
            installments: Yup.array()
                .of(
                    Yup.object({
                        date: Yup.date()
                            .required("Date is required")
                            .typeError("Invalid date"),
                        amount: Yup.number()
                            .required("Amount is required")
                            .min(1, "Amount must be at least ₹1")
                            .typeError("Invalid amount"),
                    })
                )
                .min(1, "At least one installment is required"),
        }),
        onSubmit: async (values) => {
            const validInstallments = values.installments.filter(
                inst => inst.amount > 0 && inst.date
            );

            if (validInstallments.length === 0) {
                toast.warning('Please add at least one installment with date and amount');
                return;
            }

            const missingDates = values.installments.some(inst => inst.amount > 0 && !inst.date);
            if (missingDates) {
                toast.warning('All installments with amount must have a date');
                return;
            }

            const missingAmounts = values.installments.some(inst => inst.date && (!inst.amount || inst.amount <= 0));
            if (missingAmounts) {
                toast.warning('All installments with date must have an amount');
                return;
            }

            const totalAmount = validInstallments.reduce((sum, inst) => sum + inst.amount, 0);

            if (totalAmount > balanceAmount) {
                toast.error(`Total (₹${totalAmount.toLocaleString()}) cannot exceed balance (₹${balanceAmount.toLocaleString()})`);
                return;
            }

            if (totalAmount <= 0) {
                toast.warning('Total installment amount must be greater than ₹0');
                return;
            }

            const today = new Date();
            today.setHours(0, 0, 0, 0);
            const pastDates = validInstallments.filter(inst => {
                const instDate = inst.date instanceof Date ? inst.date : new Date(inst.date!);
                return instDate < today;
            });

            if (pastDates.length > 0) {
                const confirmed = window.confirm(
                    `${pastDates.length} installment(s) have past dates. Do you want to continue?`
                );
                if (!confirmed) return;
            }

            setLoading(true);

            try {
                const payload = {
                    student_id: student?.id,
                    training_id: student?.training_id,
                    batch_id: student?.batch_id,
                    total_amount: totalFees,
                    installments: validInstallments.map(inst => ({
                        due_date: inst.date instanceof Date
                            ? inst.date.toISOString().split('T')[0]
                            : inst.date,
                        amount: inst.amount,
                    })),
                };

                const response = await api.post('/fee-management/create', payload);

                if (response.data.status) {
                    toast.success('Fee schedule created successfully');
                    onSave({
                        ...student,
                        schedule: validInstallments,
                        feeScheduleId: response.data.data.id
                    });
                    onClose();
                    formik.resetForm();
                } else {
                    toast.error(response.data.message || 'Failed to create fee schedule');
                }
            } catch (error: any) {
                console.error('Error creating fee schedule:', error);
                toast.error(error.response?.data?.message || 'Failed to create fee schedule');
            } finally {
                setLoading(false);
            }
        },
    });

    // ==========================================
    // FUNCTIONS THAT USE FORMIK - AFTER FORMIK DECLARATION
    // ==========================================

    const addInstallment = () => {
        const updated = [...formik.values.installments, { date: undefined, amount: 0 }];
        formik.setFieldValue("installments", updated);
    };

    const totalCustom = useMemo(() => {
        return (formik.values.installments || []).reduce(
            (sum, i) => sum + Number(i.amount || 0),
            0
        );
    }, [formik.values.installments]);

    const allInstallmentsValid = useMemo(() => {
        const installments = formik.values.installments || [];
        if (installments.length === 0) return false;
        return installments.every(inst => inst.date && inst.amount > 0);
    }, [formik.values.installments]);

    const isTotalExact = totalCustom === balanceAmount;
    const isTotalOver = totalCustom > balanceAmount;
    const isTotalUnder = totalCustom > 0 && totalCustom < balanceAmount;

    const canSave = useMemo(() => {
        const installments = formik.values.installments || [];
        if (installments.length === 0) return false;
        if (loading) return false;
        if (totalCustom <= 0) return false;
        if (totalCustom > balanceAmount) return false;
        if (!allInstallmentsValid) return false;
        return true;
    }, [formik.values.installments, totalCustom, balanceAmount, allInstallmentsValid, loading]);

    const handleSave = () => {
        const installments = formik.values.installments || [];

        if (installments.length === 0) {
            toast.warning('Please add at least one installment');
            return;
        }

        if (totalCustom <= 0) {
            toast.warning('Please enter installment amounts');
            return;
        }

        if (totalCustom > balanceAmount) {
            toast.error(`Total (₹${totalCustom.toLocaleString()}) exceeds balance (₹${balanceAmount.toLocaleString()})`);
            return;
        }

        if (!allInstallmentsValid) {
            toast.warning('Please fill in all dates and amounts for each installment');
            return;
        }

        formik.submitForm();
    };

    // ==========================================
    // RENDER
    // ==========================================
    return (
        <Modal
            open={open}
            onClose={onClose}
            title="Schedule Installments"
            maxWidth="max-w-3xl"
            footer={
                <>
                    <button
                        onClick={onClose}
                        className="btn btn-outline-danger"
                        type="button"
                        disabled={loading}
                    >
                        Cancel
                    </button>

                    <button
                        onClick={handleSave}
                        disabled={!canSave}
                        className={`btn btn-primary disabled:opacity-50`}
                        type="button"
                        title={
                            totalCustom > balanceAmount
                                ? 'Total exceeds balance amount'
                                : !allInstallmentsValid
                                    ? 'Fill all dates and amounts'
                                    : ''
                        }
                    >
                        {loading ? (
                            <span className="flex items-center gap-2">
                                <svg className="animate-spin h-4 w-4" viewBox="0 0 24 24">
                                    <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" fill="none" />
                                    <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
                                </svg>
                                Saving...
                            </span>
                        ) : (
                            'Save Installments'
                        )}
                    </button>
                </>
            }
        >
            <form className="space-y-4" onSubmit={(e) => e.preventDefault()}>
                {/* Student Info Card */}
                <div className="bg-gray-50 rounded-lg p-4 border">
                    <h3 className="text-black font-semibold text-base mb-2">
                        {student?.student_name || student?.name || "Student"}
                    </h3>
                    <div className="flex justify-between text-sm text-gray-600 mb-3">
                        <span className="flex items-center gap-2">
                            <IconMail className="w-4 h-4" />
                            {student?.student_email || student?.email || "-"}
                        </span>
                        <span className="flex items-center gap-2">
                            <IconPhone className="w-4 h-4" />
                            {student?.student_mobile || student?.phone || "-"}
                        </span>
                    </div>

                    <div className="grid grid-cols-3 gap-3 bg-white rounded-lg p-3">
                        <div className="text-center">
                            <div className="text-xs text-gray-500 mb-1">Total Fees</div>
                            <div className="text-blue-600 font-bold text-lg">
                                ₹{totalFees.toLocaleString()}
                            </div>
                        </div>
                        <div className="text-center">
                            <div className="text-xs text-gray-500 mb-1">Paid</div>
                            <div className="text-green-600 font-bold text-lg">
                                ₹{paidAmount.toLocaleString()}
                            </div>
                        </div>
                        <div className="text-center">
                            <div className="text-xs text-gray-500 mb-1">Balance</div>
                            <div className="text-red-600 font-bold text-lg">
                                ₹{balanceAmount.toLocaleString()}
                            </div>
                        </div>
                    </div>

                </div>

                {/* Installments Section */}
                <div className="border rounded-lg p-4">
                    <div className="flex justify-between items-center mb-3">
                        <h4 className="font-medium text-gray-700">
                            Installments
                            {totalCustom > 0 && (
                                <span className="text-xs text-gray-400 ml-2">
                                    ({formik.values.installments.length} added)
                                </span>
                            )}
                        </h4>
                        <button
                            type="button"
                            className="btn btn-sm btn-primary flex items-center gap-1"
                            onClick={addInstallment}
                        >
                            <IconPlus className="w-4 h-4" />
                            Add Installment
                        </button>
                    </div>

                    {(formik.values.installments || []).length === 0 ? (
                        <div className="text-center py-8 text-gray-400 border-2 border-dashed rounded-lg">
                            <IconCashBanknotes className="w-12 h-12 mx-auto mb-2 opacity-50" />
                            <p>No installments added yet</p>
                            <p className="text-xs">Click "Add Installment" to start</p>
                        </div>
                    ) : (
                        <div className="space-y-3">
                            <div className="grid grid-cols-12 gap-3 text-xs text-gray-500 font-medium px-2 pb-2 border-b">
                                <div className="col-span-1">#</div>
                                <div className="col-span-4">Due Date *</div>
                                <div className="col-span-4">Amount *</div>
                                <div className="col-span-3 text-right">Action</div>
                            </div>

                            {(formik.values.installments || []).map(
                                (item: Installment, index: number) => (
                                    <div
                                        key={index}
                                        className={`grid grid-cols-12 gap-3 items-center rounded-lg p-3 transition-colors ${
                                            item.amount > balanceAmount
                                                ? 'bg-red-50 border border-red-200'
                                                : 'bg-gray-50 hover:bg-gray-100'
                                        }`}
                                    >
                                        <div className="col-span-1 text-sm text-gray-500">{index + 1}</div>
                                        <div className="col-span-4">
                                            <Datepicker
                                                value={item.date ?? undefined}
                                                onChange={(date) => {
                                                    const updated = [...formik.values.installments];
                                                    let normalizedDate: Date | undefined;
                                                    if (date instanceof Date) {
                                                        normalizedDate = date;
                                                    } else if (Array.isArray(date) && date[0] instanceof Date) {
                                                        normalizedDate = date[0];
                                                    }
                                                    updated[index].date = normalizedDate;
                                                    formik.setFieldValue("installments", updated);
                                                }}
                                                placeholder="Select date"
                                            />
                                            {item.amount > 0 && !item.date && (
                                                <p className="text-red-500 text-xs mt-1">Date required</p>
                                            )}
                                        </div>
                                        <div className="col-span-4">
                                            <div className="relative">
                                                <span className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400">₹</span>
                                                <input
                                                    type="number"
                                                    placeholder="0.00"
                                                    value={item.amount || ''}
                                                    onChange={(e) => {
                                                        const updated = [...formik.values.installments];
                                                        updated[index].amount = Number(e.target.value);
                                                        formik.setFieldValue("installments", updated);
                                                    }}
                                                    className={`form-input w-full pl-7 text-right ${
                                                        item.amount > balanceAmount ? 'border-red-300' : ''
                                                    }`}
                                                />
                                            </div>
                                            {item.amount > balanceAmount && (
                                                <p className="text-red-500 text-xs mt-1">Exceeds balance!</p>
                                            )}
                                        </div>
                                        <div className="col-span-3 flex justify-end">
                                            <button
                                                type="button"
                                                onClick={() => {
                                                    const updated = formik.values.installments.filter((_, i) => i !== index);
                                                    formik.setFieldValue("installments", updated);
                                                }}
                                                className="text-red-500 hover:text-red-700 hover:bg-red-50 p-2 rounded-full"
                                            >
                                                <IconX className="w-4 h-4" />
                                            </button>
                                        </div>
                                    </div>
                                )
                            )}

                            {/* Total Summary */}
                            <div className="flex justify-between items-center pt-3 border-t mt-3">
                                <div className="text-sm text-gray-600">
                                    {formik.values.installments.length} installment(s)
                                </div>
                                <div className="flex items-center gap-3">
                                    <span className="text-sm text-gray-500">Total:</span>
                                    <span className={`text-lg font-bold ${
                                        isTotalOver ? 'text-red-600' : isTotalExact ? 'text-green-600' : 'text-orange-600'
                                    }`}>
                                        ₹{totalCustom.toLocaleString()}
                                    </span>
                                    <span className="text-sm text-gray-400">/ ₹{balanceAmount.toLocaleString()}</span>
                                </div>
                            </div>

                            {/* Progress Bar */}
                            <div className="w-full bg-gray-200 rounded-full h-2.5">
                                <div
                                    className={`h-2.5 rounded-full transition-all ${
                                        isTotalOver ? 'bg-red-500' : isTotalExact ? 'bg-green-500' : 'bg-orange-500'
                                    }`}
                                    style={{ width: `${Math.min((totalCustom / balanceAmount) * 100, 100)}%` }}
                                />
                            </div>

                            {/* Messages */}
                            {isTotalOver && (
                                <div className="flex items-center gap-2 text-red-600 text-sm bg-red-50 p-3 rounded border border-red-200">
                                    <span>⚠️</span>
                                    <div>
                                        <strong>Cannot save:</strong> Exceeds by ₹{(totalCustom - balanceAmount).toLocaleString()}
                                    </div>
                                </div>
                            )}
                            {isTotalUnder && (
                                <div className="flex items-center gap-2 text-orange-600 text-sm bg-orange-50 p-3 rounded border border-orange-200">
                                    <span>⚠️</span>
                                    <div>Remaining: ₹{(balanceAmount - totalCustom).toLocaleString()}</div>
                                </div>
                            )}
                            {isTotalExact && totalCustom > 0 && (
                                <div className="flex items-center gap-2 text-green-600 text-sm bg-green-50 p-3 rounded border border-green-200">
                                    <span>✓</span>
                                    <div><strong>Ready to save!</strong></div>
                                </div>
                            )}
                        </div>
                    )}
                </div>
            </form>
        </Modal>
    );
};

export default FeeSchedule;
