import type { LoaderFunctionArgs, ActionFunctionArgs } from "@remix-run/node";
import { json, redirect } from "@remix-run/node";
import { useLoaderData, useActionData, useNavigation, useSearchParams } from "@remix-run/react";
import { useState, useEffect } from "react";
import { requireAuth } from "~/lib/auth-middleware.server";
import { useDebounce } from "~/hooks/useDebounce";
import { 
    getExpenses, 
    createExpense, 
    updateExpense,
    deleteExpense,
    getExpenseById,
    getExpenseCategories 
} from "~/lib/expense-management.server";
import { validateExpense } from "~/lib/validation";
import { DashboardLayout } from "~/components/layout/DashboardLayout";
import { ExpenseForm } from "~/components/expenses/ExpenseForm";
import { Button } from "~/components/ui/Button";
import { Input } from "~/components/ui/Input";
import { Modal } from "~/components/ui/Modal";
import { DataTable } from "~/components/ui/DataTable";
import { Flex } from "~/components/layout/Flex";
import { useSettings } from "~/contexts/SettingsContext";
import { EXPENSE_CATEGORIES, PAGINATION } from "~/lib/constants";
import type { Expense } from "@prisma/client";

export async function loader({ request }: LoaderFunctionArgs) {
    const user = await requireAuth(request, 2); // Admin level required

    const url = new URL(request.url);
    const searchQuery = url.searchParams.get("search") || "";
    const page = parseInt(url.searchParams.get("page") || "1");
    const category = url.searchParams.get("category") || "";
    const dateFrom = url.searchParams.get("dateFrom") 
        ? new Date(url.searchParams.get("dateFrom")!) 
        : undefined;
    const dateTo = url.searchParams.get("dateTo") 
        ? new Date(url.searchParams.get("dateTo")!) 
        : undefined;

    const { expenses, total, totalPages } = await getExpenses(
        searchQuery,
        page,
        PAGINATION.DEFAULT_PAGE_SIZE,
        category,
        dateFrom,
        dateTo
    );

    const categories = await getExpenseCategories();

    return json({
        user,
        expenses,
        total,
        totalPages,
        currentPage: page,
        searchQuery,
        category,
        dateFrom: dateFrom?.toISOString().split('T')[0] || "",
        dateTo: dateTo?.toISOString().split('T')[0] || "",
        categories,
    });
}

export async function action({ request }: ActionFunctionArgs) {
    await requireAuth(request, 2); // Admin level required

    const formData = await request.formData();
    const action = formData.get("_action") as string;

    switch (action) {
        case "create": {
            const expenseData = {
                description: formData.get("description") as string,
                category: formData.get("category") as string,
                amount: parseFloat(formData.get("amount") as string),
                expenseDate: formData.get("expenseDate") as string,
            };

            const validation = validateExpense({
                description: expenseData.description,
                category: expenseData.category,
                amount: expenseData.amount,
            });

            if (!validation.isValid) {
                return json({ 
                    success: false, 
                    errors: validation.errors,
                    action: "create"
                }, { status: 400 });
            }

            try {
                const expense = await createExpense({
                    description: expenseData.description,
                    category: expenseData.category,
                    amount: expenseData.amount,
                    expenseDate: expenseData.expenseDate ? new Date(expenseData.expenseDate) : undefined,
                });

                return json({ 
                    success: true, 
                    expense,
                    action: "create",
                    message: "تم إنشاء المصروف بنجاح"
                });
            } catch (error) {
                return json({ 
                    success: false, 
                    error: "حدث خطأ أثناء إضافة المصروف",
                    action: "create"
                }, { status: 500 });
            }
        }

        case "update": {
            const id = parseInt(formData.get("id") as string);
            const expenseData = {
                description: formData.get("description") as string,
                category: formData.get("category") as string,
                amount: parseFloat(formData.get("amount") as string),
                expenseDate: formData.get("expenseDate") as string,
            };

            const validation = validateExpense({
                description: expenseData.description,
                category: expenseData.category,
                amount: expenseData.amount,
            });

            if (!validation.isValid) {
                return json({ 
                    success: false, 
                    errors: validation.errors,
                    action: "update"
                }, { status: 400 });
            }

            try {
                const expense = await updateExpense(id, {
                    description: expenseData.description,
                    category: expenseData.category,
                    amount: expenseData.amount,
                    expenseDate: expenseData.expenseDate ? new Date(expenseData.expenseDate) : undefined,
                });

                return json({ 
                    success: true, 
                    expense,
                    action: "update",
                    message: "تم تحديث المصروف بنجاح"
                });
            } catch (error) {
                return json({ 
                    success: false, 
                    error: "حدث خطأ أثناء تحديث المصروف",
                    action: "update"
                }, { status: 500 });
            }
        }

        case "delete": {
            const id = parseInt(formData.get("id") as string);

            try {
                await deleteExpense(id);
                return json({ 
                    success: true,
                    action: "delete",
                    message: "تم حذف المصروف بنجاح"
                });
            } catch (error) {
                return json({ 
                    success: false, 
                    error: "حدث خطأ أثناء حذف المصروف",
                    action: "delete"
                }, { status: 500 });
            }
        }

        case "get": {
            const id = parseInt(formData.get("id") as string);
            const expense = await getExpenseById(id);

            if (expense) {
                return json({ 
                    success: true, 
                    expense,
                    action: "get"
                });
            } else {
                return json({ 
                    success: false, 
                    error: "المصروف غير موجود",
                    action: "get"
                }, { status: 404 });
            }
        }

        default:
            return json({ 
                success: false, 
                error: "إجراء غير صحيح",
                action: "unknown"
            }, { status: 400 });
    }
}

export default function ExpensesPage() {
    const { formatCurrency, formatDate } = useSettings();
    const { 
        user,
        expenses, 
        total, 
        totalPages, 
        currentPage, 
        searchQuery, 
        category,
        dateFrom,
        dateTo,
        categories 
    } = useLoaderData<typeof loader>();
    const actionData = useActionData<typeof action>();
    const navigation = useNavigation();
    const [searchParams, setSearchParams] = useSearchParams();
    
    const [showCreateModal, setShowCreateModal] = useState(false);
    const [showEditModal, setShowEditModal] = useState(false);
    const [selectedExpense, setSelectedExpense] = useState<Expense | null>(null);
    const [searchValue, setSearchValue] = useState(searchQuery);

    const isLoading = navigation.state !== "idle";

    // Debounce search value to avoid too many requests
    const debouncedSearchValue = useDebounce(searchValue, 300);

    // Handle search automatically when debounced value changes
    useEffect(() => {
        if (debouncedSearchValue !== searchQuery) {
            const newSearchParams = new URLSearchParams(searchParams);
            if (debouncedSearchValue) {
                newSearchParams.set("search", debouncedSearchValue);
            } else {
                newSearchParams.delete("search");
            }
            newSearchParams.set("page", "1"); // Reset to first page
            setSearchParams(newSearchParams);
        }
    }, [debouncedSearchValue, searchQuery, searchParams, setSearchParams]);

    // Clear search function
    const clearSearch = () => {
        setSearchValue("");
    };

    const handleFilter = (filterType: string, value: string) => {
        const newParams = new URLSearchParams(searchParams);
        if (value) {
            newParams.set(filterType, value);
        } else {
            newParams.delete(filterType);
        }
        newParams.set("page", "1");
        setSearchParams(newParams);
    };

    // Handle pagination
    const handlePageChange = (page: number) => {
        const newParams = new URLSearchParams(searchParams);
        newParams.set("page", page.toString());
        setSearchParams(newParams);
    };

    // Handle create expense
    const handleCreateExpense = () => {
        setSelectedExpense(null);
        setShowCreateModal(true);
    };

    // Handle edit expense
    const handleEditExpense = (expense: Expense) => {
        setSelectedExpense(expense);
        setShowEditModal(true);
    };

    // Close modals on successful action
    useEffect(() => {
        if (actionData?.success && actionData.action === "create") {
            setShowCreateModal(false);
        }
        if (actionData?.success && actionData.action === "update") {
            setShowEditModal(false);
        }
    }, [actionData]);

    const columns = [
        {
            key: "description",
            header: "الوصف",
            render: (expense: Expense) => expense.description,
        },
        {
            key: "category",
            header: "الفئة",
            render: (expense: Expense) => {
                const categoryLabel = EXPENSE_CATEGORIES.find(c => c.value === expense.category)?.label;
                return categoryLabel || expense.category;
            },
        },
        {
            key: "amount",
            header: "المبلغ",
            render: (expense: Expense) => formatCurrency(expense.amount),
        },
        {
            key: "expenseDate",
            header: "تاريخ المصروف",
            render: (expense: Expense) => formatDate(expense.expenseDate),
        },
        {
            key: "createdDate",
            header: "تاريخ الإضافة",
            render: (expense: Expense) => formatDate(expense.createdDate),
        },
        {
            key: "actions",
            header: "الإجراءات",
            render: (expense: Expense) => (
                <div className="flex gap-2">
                    <Button
                        variant="outline"
                        size="sm"
                        onClick={() => handleEditExpense(expense)}
                        disabled={isLoading}
                    >
                        تعديل
                    </Button>
                </div>
            ),
        },
    ];

    return (
        <DashboardLayout user={user}>
            <div className="space-y-6">
                {/* Header */}
                <Flex justify="between" align="center" className="flex-wrap gap-4">
                    <div>
                        <h1 className="text-2xl font-bold text-gray-900">إدارة المصروفات</h1>
                        <p className="text-gray-600 mt-1">
                            إجمالي المصروفات: {total}
                        </p>
                    </div>
                    
                    <Button
                        onClick={handleCreateExpense}
                        disabled={isLoading}
                        className="bg-blue-600 hover:bg-blue-700"
                    >
                        إضافة مصروف جديد
                    </Button>
                </Flex>

                {/* Search */}
                <div className="bg-white p-4 rounded-lg shadow-sm border">
                    <Flex gap="md" align="center" className="flex-wrap">
                        <div className="flex-1 min-w-64">
                            <Input
                                type="text"
                                placeholder="البحث في المصروفات... (البحث تلقائي)"
                                value={searchValue}
                                onChange={(e) => setSearchValue(e.target.value)}
                                startIcon={
                                    <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
                                    </svg>
                                }
                                endIcon={
                                    searchValue && (
                                        <div className="pointer-events-auto">
                                            <button
                                                onClick={clearSearch}
                                                className="text-gray-400 hover:text-gray-600"
                                                type="button"
                                            >
                                                <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
                                                </svg>
                                            </button>
                                        </div>
                                    )
                                }
                            />
                        </div>
                        {(searchQuery || debouncedSearchValue !== searchQuery) && (
                            <div className="flex items-center text-sm text-gray-500">
                                {debouncedSearchValue !== searchQuery && (
                                    <span className="flex items-center">
                                        <svg className="animate-spin -ml-1 mr-2 h-4 w-4" fill="none" viewBox="0 0 24 24">
                                            <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
                                            <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
                                        </svg>
                                        جاري البحث...
                                    </span>
                                )}
                            </div>
                        )}
                    </Flex>
                </div>

                {/* Filters */}
                <div className="bg-white p-4 rounded-lg shadow-sm border">
                    <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
                        <select
                            className="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
                            value={category}
                            onChange={(e) => handleFilter("category", e.target.value)}
                        >
                            <option value="">جميع الفئات</option>
                            {EXPENSE_CATEGORIES.map((cat) => (
                                <option key={cat.value} value={cat.value}>
                                    {cat.label}
                                </option>
                            ))}
                        </select>

                        <Input
                            type="date"
                            placeholder="من تاريخ"
                            value={dateFrom}
                            onChange={(e) => handleFilter("dateFrom", e.target.value)}
                        />

                        <Input
                            type="date"
                            placeholder="إلى تاريخ"
                            value={dateTo}
                            onChange={(e) => handleFilter("dateTo", e.target.value)}
                        />
                    </div>
                </div>

                {/* Action Messages */}
                {actionData?.success && 'message' in actionData && actionData.message && (
                    <div className="bg-green-50 border border-green-200 text-green-800 px-4 py-3 rounded-lg">
                        {actionData.message}
                    </div>
                )}
                
                {actionData && !actionData.success && 'error' in actionData && actionData.error && (
                    <div className="bg-red-50 border border-red-200 text-red-800 px-4 py-3 rounded-lg">
                        {actionData.error}
                    </div>
                )}

                {/* Expenses Table */}
                <div className="bg-white rounded-lg shadow-sm border">
                    {expenses.length === 0 ? (
                        <div className="text-center py-12">
                            <div className="text-gray-400 text-lg mb-2">💰</div>
                            <h3 className="text-lg font-medium text-gray-900 mb-2">
                                لا توجد مصروفات
                            </h3>
                            <p className="text-gray-500">
                                لم يتم العثور على أي مصروفات.
                            </p>
                        </div>
                    ) : (
                        <>
                            {/* Desktop Table View */}
                            <div className="hidden md:block">
                                <DataTable
                                    data={expenses as any}
                                    columns={columns}
                                    emptyMessage="لم يتم العثور على أي مصروفات"
                                />
                            </div>

                            {/* Mobile Card View */}
                            <div className="md:hidden divide-y divide-gray-200">
                                {expenses.map((expense: any) => {
                                    const categoryLabel = EXPENSE_CATEGORIES.find(c => c.value === expense.category)?.label;
                                    return (
                                        <div key={expense.id} className="p-4 hover:bg-gray-50">
                                            <div className="space-y-3">
                                                <div className="flex justify-between items-start">
                                                    <div className="flex-1">
                                                        <div className="font-medium text-gray-900">{expense.description}</div>
                                                        <div className="text-sm text-gray-500 mt-1">{categoryLabel || expense.category}</div>
                                                    </div>
                                                    <div className="text-lg font-semibold text-gray-900">
                                                        {formatCurrency(expense.amount)}
                                                    </div>
                                                </div>
                                                
                                                <div className="grid grid-cols-2 gap-2 text-sm">
                                                    <div>
                                                        <span className="text-gray-600">تاريخ المصروف: </span>
                                                        <span className="text-gray-900">{formatDate(expense.expenseDate)}</span>
                                                    </div>
                                                    <div>
                                                        <span className="text-gray-600">تاريخ الإضافة: </span>
                                                        <span className="text-gray-900">{formatDate(expense.createdDate)}</span>
                                                    </div>
                                                </div>
                                                
                                                <div className="pt-2">
                                                    <Button
                                                        variant="outline"
                                                        size="sm"
                                                        onClick={() => handleEditExpense(expense)}
                                                        disabled={isLoading}
                                                        className="w-full"
                                                    >
                                                        تعديل
                                                    </Button>
                                                </div>
                                            </div>
                                        </div>
                                    );
                                })}
                            </div>
                        </>
                    )}
                    
                    {/* Pagination */}
                    {totalPages > 1 && (
                        <div className="px-4 py-3 border-t border-gray-200 bg-gray-50">
                            <div className="flex items-center justify-between">
                                <div className="flex items-center space-x-2 space-x-reverse">
                                    <button
                                        onClick={() => handlePageChange(currentPage - 1)}
                                        disabled={currentPage === 1 || isLoading}
                                        className="px-3 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-md hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed"
                                    >
                                        السابق
                                    </button>
                                    
                                    <div className="flex items-center space-x-1 space-x-reverse">
                                        {Array.from({ length: Math.min(5, totalPages) }, (_, i) => {
                                            const page = i + 1;
                                            return (
                                                <button
                                                    key={page}
                                                    onClick={() => handlePageChange(page)}
                                                    disabled={isLoading}
                                                    className={`px-3 py-2 text-sm font-medium rounded-md ${
                                                        currentPage === page
                                                            ? 'bg-blue-600 text-white'
                                                            : 'text-gray-500 bg-white border border-gray-300 hover:bg-gray-50'
                                                    } disabled:opacity-50 disabled:cursor-not-allowed`}
                                                >
                                                    {page}
                                                </button>
                                            );
                                        })}
                                    </div>
                                    
                                    <button
                                        onClick={() => handlePageChange(currentPage + 1)}
                                        disabled={currentPage === totalPages || isLoading}
                                        className="px-3 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-md hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed"
                                    >
                                        التالي
                                    </button>
                                </div>
                                
                                <p className="text-sm text-gray-500">
                                    صفحة {currentPage} من {totalPages}
                                </p>
                            </div>
                        </div>
                    )}
                </div>

                {/* Create Expense Modal */}
                <Modal
                    isOpen={showCreateModal}
                    onClose={() => setShowCreateModal(false)}
                    title="إضافة مصروف جديد"
                >
                    <ExpenseForm
                        onCancel={() => setShowCreateModal(false)}
                        errors={actionData && 'errors' in actionData ? actionData.errors : undefined}
                        isLoading={isLoading}
                    />
                </Modal>

                {/* Edit Expense Modal */}
                <Modal
                    isOpen={showEditModal}
                    onClose={() => setShowEditModal(false)}
                    title="تعديل المصروف"
                >
                    {selectedExpense && (
                        <ExpenseForm
                            expense={selectedExpense}
                            onCancel={() => setShowEditModal(false)}
                            errors={actionData && 'errors' in actionData ? actionData.errors : undefined}
                            isLoading={isLoading}
                        />
                    )}
                </Modal>
            </div>
        </DashboardLayout>
    );
}