import { useState, useEffect, useCallback } from "react";

import { getAppointmentsApi, deleteAppointmentApi } from "@/api/appointment";
import { exportToExcel } from "@/utils/exportToExcel";

import {
	Table,
	TableBody,
	TableCell,
	TableHead,
	TableHeader,
	TableRow,
} from "@/components/ui/table";

import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";

import {
	Loader2,
	Trash,
	RefreshCw,
	Download,
	ChevronLeft,
	ChevronRight,
} from "lucide-react";

export default function AppointmentPage() {
	const [appointments, setAppointments] = useState<any[]>([]);
	const [loading, setLoading] = useState(true);

	const [searchText, setSearchText] = useState("");
	const [filterDoctor, setFilterDoctor] = useState("");
	const [filterDepartment, setFilterDepartment] = useState("");
	const [filterDate, setFilterDate] = useState("");

	const [currentPage, setCurrentPage] = useState(1);
	const [itemsPerPage, setItemsPerPage] = useState(10);

	const [meta, setMeta] = useState<any>({});

	const fetchAll = useCallback(async () => {
		setLoading(true);
		try {
			const res = await getAppointmentsApi(
				currentPage,
				itemsPerPage,
				searchText,
				filterDoctor,
				filterDepartment,
				filterDate,
			);

			setAppointments(res?.data || []);
			setMeta(res?.meta || {});
		} catch (err) {
			console.error(err);
		} finally {
			setLoading(false);
		}
	}, [
		currentPage,
		itemsPerPage,
		searchText,
		filterDoctor,
		filterDepartment,
		filterDate,
	]);

	useEffect(() => {
		fetchAll();
	}, [fetchAll]);

	async function handleDelete(id: number) {
		if (!confirm("Delete appointment?")) return;
		await deleteAppointmentApi(id);
		fetchAll();
	}

	const handleExport = async () => {
		try {
			const res = await getAppointmentsApi();

			let data = res?.data || [];

			data = data.filter((item: any) => {
				const matchesSearch =
					item.name?.toLowerCase().includes(searchText.toLowerCase()) ||
					item.mobileNumber?.includes(searchText) ||
					item.email?.toLowerCase().includes(searchText.toLowerCase());

				const matchesDoctor = filterDoctor
					? item.doctor?.name
							?.toLowerCase()
							.includes(filterDoctor.toLowerCase())
					: true;

				const matchesDepartment = filterDepartment
					? item.department?.name
							?.toLowerCase()
							.includes(filterDepartment.toLowerCase())
					: true;

				const matchesDate = filterDate
					? new Date(item.date).toISOString().split("T")[0] === filterDate
					: true;

				return (
					matchesSearch && matchesDoctor && matchesDepartment && matchesDate
				);
			});

			const exportData = data.map((item: any) => ({
				ID: item.id,
				Name: item.name,
				Phone: item.mobileNumber,
				Email: item.email,
				Doctor: item.doctor?.name,
				Department: item.department?.name,
				Date: new Date(item.date).toLocaleDateString(),
				Message: item.message,
			}));

			exportToExcel(exportData, "appointments");
		} catch (err) {
			console.error(err);
		}
	};

	return (
		<div className="p-6 space-y-6">
			<div className="flex justify-between items-center flex-wrap gap-3">
				<h1 className="text-2xl font-bold">Appointments</h1>

				<div className="flex flex-wrap gap-2 items-center">
					<Input
						placeholder="Search..."
						value={searchText}
						onChange={(e) => {
							setSearchText(e.target.value);
							setCurrentPage(1);
						}}
						className="w-[200px]"
					/>

					<Input
						placeholder="Doctor"
						value={filterDoctor}
						onChange={(e) => setFilterDoctor(e.target.value)}
						className="w-[160px]"
					/>

					<Input
						placeholder="Department"
						value={filterDepartment}
						onChange={(e) => setFilterDepartment(e.target.value)}
						className="w-[160px]"
					/>

					<Input
						type="date"
						value={filterDate}
						onChange={(e) => setFilterDate(e.target.value)}
						className="w-[160px]"
					/>

					<select
						value={itemsPerPage}
						onChange={(e) => {
							setItemsPerPage(Number(e.target.value));
							setCurrentPage(1);
						}}
						className="border px-2 py-1 rounded">
						<option value={5}>5</option>
						<option value={10}>10</option>
						<option value={20}>20</option>
					</select>

					<Button onClick={fetchAll}>
						<RefreshCw className="mr-2 h-4 w-4" />
					</Button>

					<Button onClick={handleExport}>
						<Download className="mr-2 h-4 w-4" />
						Export
					</Button>
				</div>
			</div>

			<Card>
				<CardHeader>
					<CardTitle>Appointment List</CardTitle>
				</CardHeader>

				<CardContent>
					<Table>
						<TableHeader>
							<TableRow>
								<TableHead>ID</TableHead>
								<TableHead>Name</TableHead>
								<TableHead>Phone</TableHead>
								<TableHead>Doctor</TableHead>
								<TableHead>Department</TableHead>
								<TableHead>Date</TableHead>
								<TableHead>Actions</TableHead>
							</TableRow>
						</TableHeader>

						<TableBody>
							{loading ? (
								<TableRow>
									<TableCell colSpan={7} className="text-center">
										<Loader2 className="animate-spin mx-auto" />
									</TableCell>
								</TableRow>
							) : appointments.length === 0 ? (
								<TableRow>
									<TableCell
										colSpan={7}
										className="text-center py-6 text-gray-500">
										No appointments found
									</TableCell>
								</TableRow>
							) : (
								appointments.map((item) => (
									<TableRow key={item.id}>
										<TableCell>{item.id}</TableCell>
										<TableCell>{item.name}</TableCell>
										<TableCell>{item.mobileNumber}</TableCell>
										<TableCell>{item.doctor?.name}</TableCell>
										<TableCell>{item.department?.name}</TableCell>
										<TableCell>
											{new Date(item.date).toLocaleDateString()}
										</TableCell>
										<TableCell>
											<Button
												size="sm"
												variant="destructive"
												onClick={() => handleDelete(item.id)}>
												<Trash className="h-4 w-4" />
											</Button>
										</TableCell>
									</TableRow>
								))
							)}
						</TableBody>
					</Table>

					<div className="flex justify-between mt-4">
						<p>
							Page {meta.page || 1} of {meta.totalPages || 1}
						</p>

						<div className="flex gap-2">
							<Button
								disabled={currentPage === 1}
								onClick={() => setCurrentPage((p) => p - 1)}>
								<ChevronLeft />
							</Button>

							<Button
								disabled={currentPage === meta.totalPages}
								onClick={() => setCurrentPage((p) => p + 1)}>
								<ChevronRight />
							</Button>
						</div>
					</div>
				</CardContent>
			</Card>
		</div>
	);
}
