import {useState, useEffect, useCallback} from "react";
import {
	getDoctorsApi,
	createDoctorApi,
	updateDoctorApi,
	deleteDoctorApi,
	getDoctorTimingApi,
} from "@/api/doctor";

import {getDepartmentsApi} from "@/api/department";

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 {
	Dialog,
	DialogContent,
	DialogHeader,
	DialogTitle,
	DialogFooter,
} from "@/components/ui/dialog";

import {Popover, PopoverContent, PopoverTrigger} from "@/components/ui/popover";
import {
	Command,
	CommandGroup,
	CommandItem,
	CommandInput,
} from "@/components/ui/command";

import {Input} from "@/components/ui/input";
import {Loader2, Plus, Pencil, Trash, RefreshCw} from "lucide-react";

interface Department {
	departmentId: string;
	name: string;
}

export default function DoctorPage() {
	const [doctors, setDoctors] = useState<any[]>([]);
	const [departments, setDepartments] = useState<Department[]>([]);
	const [loading, setLoading] = useState(true);
	const [openModal, setOpenModal] = useState(false);
	const [editing, setEditing] = useState<any>(null);

	const [searchText, setSearchText] = useState("");
	const [filterDepartment, setFilterDepartment] = useState("");

	const [form, setForm] = useState<any>({
		doctorId: "",
		name: "",
		designation: "",
		workingStatus: "",
		qualification: "",
		departments: [],
	});

	const fetchAll = useCallback(async () => {
		setLoading(true);
		try {
			const [docRes, depRes] = await Promise.all([
				getDoctorsApi(),
				getDepartmentsApi(),
			]);

			setDoctors(docRes?.data || []);
			setDepartments(depRes?.data || []);
		} catch (err) {
			console.error(err);
		} finally {
			setLoading(false);
		}
	}, []);

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

	const filteredDoctors = doctors.filter((doc) => {
		const matchesSearch =
			doc.name.toLowerCase().includes(searchText.toLowerCase()) ||
			doc.doctorId.toLowerCase().includes(searchText.toLowerCase());

		const matchesDepartment = filterDepartment
			? doc.departments?.some((d: any) => d.departmentId === filterDepartment)
			: true;

		return matchesSearch && matchesDepartment;
	});

	function handleChange(e: any) {
		setForm({...form, [e.target.name]: e.target.value});
	}

	function handleDepartmentChange(depId: string) {
		const exists = form.departments.find((d: any) => d.departmentId === depId);

		if (exists) {
			setForm({
				...form,
				departments: form.departments.filter(
					(d: any) => d.departmentId !== depId,
				),
			});
		} else {
			setForm({
				...form,
				departments: [...form.departments, {departmentId: depId, timing: {}}],
			});
		}
	}

	function handleTimingChange(depId: string, day: string, value: string) {
		setForm({
			...form,
			departments: form.departments.map((d: any) =>
				d.departmentId === depId
					? {
							...d,
							timing: {...d.timing, [day]: value},
						}
					: d,
			),
		});
	}

	function openAdd() {
		setEditing(null);
		setForm({
			doctorId: "",
			name: "",
			designation: "",
			workingStatus: "",
			qualification: "",
			departments: [],
		});
		setOpenModal(true);
	}

	async function openEdit(doc: any) {
		setEditing(doc);

		try {
			const timingRes = await getDoctorTimingApi(doc.doctorId);
			const timingData = timingRes?.data?.departments || [];

			const mappedDepartments = timingData.map((d: any) => ({
				departmentId: d.departmentId,
				timing: d.timing || {},
			}));

			setForm({
				doctorId: doc.doctorId,
				name: doc.name,
				designation: doc.designation,
				workingStatus: doc.workingStatus,
				qualification: doc.qualification,
				departments: mappedDepartments,
			});

			setOpenModal(true);
		} catch (err) {
			console.error(err);
		}
	}

	async function handleSubmit() {
		try {
			if (editing) {
				await updateDoctorApi(editing.doctorId, form);
			} else {
				await createDoctorApi(form);
			}

			setOpenModal(false);
			fetchAll();
		} catch (err) {
			console.error(err);
		}
	}

	async function handleDelete(id: string) {
		if (!confirm("Delete doctor?")) return;
		await deleteDoctorApi(id);
		fetchAll();
	}

	return (
		<div className="p-6 space-y-6">
			{/* HEADER */}
			<div className="flex flex-col md:flex-row md:justify-between md:items-center gap-3">
				<h1 className="text-2xl font-bold">Doctors</h1>

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

					<select
						value={filterDepartment}
						onChange={(e) => setFilterDepartment(e.target.value)}
						className="border rounded px-2 py-1"
					>
						<option value="">All Departments</option>
						{departments.map((dep) => (
							<option key={dep.departmentId} value={dep.departmentId}>
								{dep.name}
							</option>
						))}
					</select>

					<Button variant="outline" onClick={fetchAll} disabled={loading}>
						<RefreshCw className="mr-2 h-4 w-4" />
						Refresh
					</Button>

					<Button onClick={openAdd}>
						<Plus className="mr-2 h-4 w-4" />
						Add Doctor
					</Button>
				</div>
			</div>

			{/* TABLE */}
			<Card>
				<CardHeader>
					<CardTitle>Doctor List</CardTitle>
				</CardHeader>

				<CardContent>
					<div className="overflow-x-auto">
						<Table className="min-w-[1000px]">
							<TableHeader>
								<TableRow>
									<TableHead>ID</TableHead>
									<TableHead>Name</TableHead>
									<TableHead>Designation</TableHead>
									<TableHead>Status</TableHead>
									<TableHead>Qualification</TableHead>
									<TableHead>Departments</TableHead>
									<TableHead>Timing</TableHead>
									<TableHead>Actions</TableHead>
								</TableRow>
							</TableHeader>

							<TableBody>
								{loading ? (
									<TableRow>
										<TableCell colSpan={8} className="text-center">
											<Loader2 className="h-6 w-6 animate-spin mx-auto" />
										</TableCell>
									</TableRow>
								) : filteredDoctors.length === 0 ? (
									<TableRow>
										<TableCell colSpan={8} className="text-center">
											No doctors found
										</TableCell>
									</TableRow>
								) : (
									filteredDoctors.map((doc) => (
										<TableRow key={doc.doctorId}>
											<TableCell>{doc.doctorId}</TableCell>
											<TableCell>{doc.name}</TableCell>
											<TableCell>{doc.designation}</TableCell>
											<TableCell>{doc.workingStatus}</TableCell>
											<TableCell>{doc.qualification}</TableCell>

											<TableCell>
												{doc.departments
													?.map((d: any) => d.departmentName)
													.join(", ")}
											</TableCell>

											<TableCell className="max-w-[250px] whitespace-normal">
												{doc.departments?.map((d: any) => (
													<div key={d.departmentId}>
														<b>{d.departmentName}:</b>{" "}
														{JSON.stringify(d.timing)}
													</div>
												))}
											</TableCell>

											<TableCell className="flex gap-2">
												<Button
													size="sm"
													variant="outline"
													onClick={() => openEdit(doc)}
												>
													<Pencil className="h-4 w-4" />
												</Button>

												<Button
													size="sm"
													variant="destructive"
													onClick={() => handleDelete(doc.doctorId)}
												>
													<Trash className="h-4 w-4" />
												</Button>
											</TableCell>
										</TableRow>
									))
								)}
							</TableBody>
						</Table>
					</div>
				</CardContent>
			</Card>

			{/* MODAL */}
			{/* MODAL */}
			<Dialog open={openModal} onOpenChange={setOpenModal}>
				<DialogContent className="overflow-y-auto max-h-[80vh] ">
					<DialogHeader>
						<DialogTitle>{editing ? "Edit Doctor" : "Add Doctor"}</DialogTitle>
					</DialogHeader>

					<div className="space-y-4">
						<Input
							name="doctorId"
							placeholder="Doctor ID"
							value={form.doctorId}
							onChange={handleChange}
							disabled={!!editing}
						/>

						<Input
							name="name"
							placeholder="Name"
							value={form.name}
							onChange={handleChange}
						/>
						<Input
							name="designation"
							placeholder="Designation"
							value={form.designation}
							onChange={handleChange}
						/>
						<Input
							name="workingStatus"
							placeholder="Working Status"
							value={form.workingStatus}
							onChange={handleChange}
						/>
						<Input
							name="qualification"
							placeholder="Qualification"
							value={form.qualification}
							onChange={handleChange}
						/>

						{/* Departments */}
						<div>
							<p className="font-medium mb-2">Departments</p>

							<Popover>
								<PopoverTrigger asChild>
									<Button className="w-full justify-between h-auto min-h-[40px]">
										{form.departments.length > 0 ? (
											<div className="flex flex-col items-start gap-1 text-left">
												{form.departments.map((d: any) => {
													const name = departments.find(
														(dep) => dep.departmentId === d.departmentId,
													)?.name;

													return (
														<span key={d.departmentId} className="text-sm">
															{name}
														</span>
													);
												})}
											</div>
										) : (
											<span>Select Departments</span>
										)}
									</Button>
								</PopoverTrigger>

								<PopoverContent className="w-[300px] p-0">
									<Command>
										<CommandInput placeholder="Search department..." />

										<CommandGroup className="max-h-[250px] overflow-y-auto">
											{departments.map((dep) => {
												const selected = form.departments.some(
													(d: any) => d.departmentId === dep.departmentId,
												);

												return (
													<CommandItem
														key={dep.departmentId}
														className="flex justify-between"
														onSelect={() =>
															handleDepartmentChange(dep.departmentId)
														}
													>
														<span>{dep.name}</span>
														{selected && <span>✔</span>}
													</CommandItem>
												);
											})}
										</CommandGroup>
									</Command>
								</PopoverContent>
							</Popover>
						</div>

						{form.departments.map((dep: any) => {
							const depName = departments.find(
								(d) => d.departmentId === dep.departmentId,
							)?.name;

							return (
								<div
									key={dep.departmentId}
									className="tw-border tw-p-3 tw-rounded"
								>
									<p className="tw-font-semibold">{depName}</p>

									{[
										"monday",
										"tuesday",
										"wednesday",
										"thursday",
										"friday",
										"saturday",
										"sunday",
										"additional",
									].map((day) => (
										<Input
											key={day}
											placeholder={day}
											value={dep.timing?.[day] || ""}
											onChange={(e) =>
												handleTimingChange(
													dep.departmentId,
													day,
													e.target.value,
												)
											}
										/>
									))}
								</div>
							);
						})}
					</div>

					<DialogFooter>
						<Button variant="outline" onClick={() => setOpenModal(false)}>
							Cancel
						</Button>
						<Button onClick={handleSubmit}>
							{editing ? "Update" : "Create"}
						</Button>
					</DialogFooter>
				</DialogContent>
			</Dialog>
		</div>
	);
}
