import React, { useEffect, useMemo, useState } from "react";
import { useSearchParams } from "react-router-dom";
import { apiClient } from "../lib/api";
import type {
	SearchPriorityFilter,
	Task,
	TaskSearchResult,
} from "../../types";
import CleanupModal from "./CleanupModal";
import { SuccessToast } from "./SuccessToast";

interface TaskListProps {
	onEditTask: (task: Task) => void;
	onNewTask: () => void;
	tasks: Task[];
	availableStatuses: string[];
	onRefreshData?: () => Promise<void>;
	onUpdateTask?: (taskId: string, updates: Partial<Task>) => Promise<void>;
}

const PRIORITY_OPTIONS: Array<{ label: string; value: "" | SearchPriorityFilter }> = [
	{ label: "All priorities", value: "" },
	{ label: "High", value: "high" },
	{ label: "Medium", value: "medium" },
	{ label: "Low", value: "low" },
];

function sortTasksByIdDescending(list: Task[]): Task[] {
	return [...list].sort((a, b) => {
		const idA = Number.parseInt(a.id.replace("task-", ""), 10);
		const idB = Number.parseInt(b.id.replace("task-", ""), 10);
		return idB - idA;
	});
}

const TaskList: React.FC<TaskListProps> = ({ onEditTask, onNewTask, tasks, availableStatuses, onRefreshData, onUpdateTask }) => {
	const [searchParams, setSearchParams] = useSearchParams();
	const [searchValue, setSearchValue] = useState(() => searchParams.get("query") ?? "");
	const [statusFilter, setStatusFilter] = useState(() => searchParams.get("status") ?? "");
	const [priorityFilter, setPriorityFilter] = useState<"" | SearchPriorityFilter>(
		() => (searchParams.get("priority") as SearchPriorityFilter | null) ?? "",
	);
	const [doTodayFilter, setDoTodayFilter] = useState(() => searchParams.get("doToday") === "true");
	const [labelFilters, setLabelFilters] = useState<string[]>(() => {
		const labels = searchParams.get("labels");
		return labels ? labels.split(",").filter(Boolean) : [];
	});
	const [displayTasks, setDisplayTasks] = useState<Task[]>(() => sortTasksByIdDescending(tasks));
	const [error, setError] = useState<string | null>(null);
	const [showCleanupModal, setShowCleanupModal] = useState(false);
	const [cleanupSuccessMessage, setCleanupSuccessMessage] = useState<string | null>(null);

	const sortedBaseTasks = useMemo(() => sortTasksByIdDescending(tasks), [tasks]);
	const normalizedSearch = searchValue.trim();
	const hasActiveFilters = Boolean(normalizedSearch || statusFilter || priorityFilter || doTodayFilter || labelFilters.length > 0);
	const totalTasks = sortedBaseTasks.length;

	useEffect(() => {
		const paramQuery = searchParams.get("query") ?? "";
		const paramStatus = searchParams.get("status") ?? "";
		const paramPriority = (searchParams.get("priority") as SearchPriorityFilter | null) ?? "";
		const paramDoToday = searchParams.get("doToday") === "true";
		const paramLabels = searchParams.get("labels");
		const labelsArray = paramLabels ? paramLabels.split(",").filter(Boolean) : [];

		if (paramQuery !== searchValue) {
			setSearchValue(paramQuery);
		}
		if (paramStatus !== statusFilter) {
			setStatusFilter(paramStatus);
		}
		if (paramPriority !== priorityFilter) {
			setPriorityFilter(paramPriority);
		}
		if (paramDoToday !== doTodayFilter) {
			setDoTodayFilter(paramDoToday);
		}
		if (JSON.stringify(labelsArray) !== JSON.stringify(labelFilters)) {
			setLabelFilters(labelsArray);
		}
	}, [searchParams]);

	useEffect(() => {
		if (!hasActiveFilters) {
			setDisplayTasks(sortedBaseTasks);
			setError(null);
		}
	}, [hasActiveFilters, sortedBaseTasks]);

	useEffect(() => {
		if (!hasActiveFilters) {
			return;
		}

		let cancelled = false;
		setError(null);

		const fetchFilteredTasks = async () => {
			try {
				// First get base results from API (for text search, status, priority)
				let filteredTasks: Task[];
				if (normalizedSearch || statusFilter || priorityFilter) {
					const results = await apiClient.search({
						query: normalizedSearch || undefined,
						types: ["task"],
						status: statusFilter || undefined,
						priority: (priorityFilter || undefined) as SearchPriorityFilter | undefined,
					});
					if (cancelled) {
						return;
					}
					const taskResults = results.filter((result): result is TaskSearchResult => result.type === "task");
					filteredTasks = taskResults.map((result) => result.task);
				} else {
					filteredTasks = tasks;
				}

				// Apply client-side filters for doToday and labels
				if (doTodayFilter) {
					filteredTasks = filteredTasks.filter(task => task.doToday === true);
				}
				if (labelFilters.length > 0) {
					filteredTasks = filteredTasks.filter(task =>
						labelFilters.every(label => task.labels.includes(label))
					);
				}

				setDisplayTasks(sortTasksByIdDescending(filteredTasks));
			} catch (err) {
				console.error("Failed to apply task filters:", err);
				if (!cancelled) {
					setDisplayTasks([]);
					setError("Unable to fetch tasks for the selected filters.");
				}
			}
		};

		fetchFilteredTasks();

		return () => {
			cancelled = true;
		};
	}, [hasActiveFilters, normalizedSearch, priorityFilter, statusFilter, doTodayFilter, labelFilters, tasks]);

	const syncUrl = (
		nextQuery: string,
		nextStatus: string,
		nextPriority: "" | SearchPriorityFilter,
		nextDoToday: boolean = doTodayFilter,
		nextLabels: string[] = labelFilters
	) => {
		const params = new URLSearchParams();
		const trimmedQuery = nextQuery.trim();
		if (trimmedQuery) {
			params.set("query", trimmedQuery);
		}
		if (nextStatus) {
			params.set("status", nextStatus);
		}
		if (nextPriority) {
			params.set("priority", nextPriority);
		}
		if (nextDoToday) {
			params.set("doToday", "true");
		}
		if (nextLabels.length > 0) {
			params.set("labels", nextLabels.join(","));
		}
		setSearchParams(params, { replace: true });
	};

	const handleSearchChange = (value: string) => {
		setSearchValue(value);
		syncUrl(value, statusFilter, priorityFilter);
	};

	const handleStatusChange = (value: string) => {
		setStatusFilter(value);
		syncUrl(searchValue, value, priorityFilter);
	};

	const handlePriorityChange = (value: "" | SearchPriorityFilter) => {
		setPriorityFilter(value);
		syncUrl(searchValue, statusFilter, value);
	};

	const handleDoTodayToggle = () => {
		const newValue = !doTodayFilter;
		setDoTodayFilter(newValue);
		syncUrl(searchValue, statusFilter, priorityFilter, newValue, labelFilters);
	};

	const handleLabelToggle = (label: string) => {
		const newLabels = labelFilters.includes(label)
			? labelFilters.filter(l => l !== label)
			: [...labelFilters, label];
		setLabelFilters(newLabels);
		syncUrl(searchValue, statusFilter, priorityFilter, doTodayFilter, newLabels);
	};

	const handleToggleDoToday = async (taskId: string, doToday: boolean) => {
		if (onUpdateTask) {
			await onUpdateTask(taskId, { doToday });
		}
	};

	const handleClearFilters = () => {
		setSearchValue("");
		setStatusFilter("");
		setPriorityFilter("");
		setDoTodayFilter(false);
		setLabelFilters([]);
		syncUrl("", "", "", false, []);
		setDisplayTasks(sortedBaseTasks);
		setError(null);
	};

	const handleCleanupSuccess = async (movedCount: number) => {
		setShowCleanupModal(false);
		setCleanupSuccessMessage(`Successfully moved ${movedCount} task${movedCount !== 1 ? 's' : ''} to completed folder`);

		// Refresh the data - existing effects will handle re-filtering automatically
		if (onRefreshData) {
			await onRefreshData();
		}

		// Auto-dismiss success message after 4 seconds
		setTimeout(() => {
			setCleanupSuccessMessage(null);
		}, 4000);
	};

	const getStatusColor = (status: string) => {
		switch (status.toLowerCase()) {
			case "to do":
				return "bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-200";
			case "in progress":
				return "bg-blue-100 text-blue-800 dark:bg-blue-900/50 dark:text-blue-200";
			case "done":
				return "bg-green-100 text-green-800 dark:bg-green-900/50 dark:text-green-200";
			default:
				return "bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-200";
		}
	};

	const getPriorityColor = (priority?: string) => {
		switch (priority?.toLowerCase()) {
			case "high":
				return "bg-red-100 text-red-800 dark:bg-red-900/50 dark:text-red-200";
			case "medium":
				return "bg-yellow-100 text-yellow-800 dark:bg-yellow-900/50 dark:text-yellow-200";
			case "low":
				return "bg-green-100 text-green-800 dark:bg-green-900/50 dark:text-green-200";
			default:
				return "bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-200";
		}
	};

	const currentCount = displayTasks.length;

	return (
		<div className="container mx-auto px-4 py-8 transition-colors duration-200">
			<div className="flex flex-col gap-4 mb-6">
				<div className="flex items-center justify-between">
					<h1 className="text-2xl font-bold text-gray-900 dark:text-white">All Tasks</h1>
					<button
						className="inline-flex items-center px-4 py-2 bg-blue-500 text-white text-sm font-medium rounded-md hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-400 dark:focus:ring-offset-gray-900 transition-colors duration-200 cursor-pointer"
						onClick={onNewTask}
					>
						+ New Task
					</button>
				</div>

				<div className="flex flex-wrap items-center gap-3">
					<div className="relative flex-1 min-w-[220px]">
						<span className="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3 text-gray-400 dark:text-gray-500">
							<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>
						</span>
						<input
							type="text"
							value={searchValue}
							onChange={(event) => handleSearchChange(event.target.value)}
							placeholder="Search tasks"
							className="w-full pl-10 pr-10 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-sm text-gray-900 dark:text-gray-100 placeholder-gray-500 dark:placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-stone-500 dark:focus:ring-stone-400 focus:border-transparent transition-colors duration-200"
						/>
						{searchValue && (
							<button
								type="button"
								onClick={() => handleSearchChange("")}
								className="absolute inset-y-0 right-0 flex items-center pr-3 text-gray-400 dark:text-gray-500 hover:text-gray-600 dark:hover:text-gray-300 cursor-pointer"
							>
								<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>

					<select
						value={statusFilter}
						onChange={(event) => handleStatusChange(event.target.value)}
						className="min-w-[160px] py-2 px-3 text-sm border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-stone-500 dark:focus:ring-stone-400 transition-colors duration-200"
					>
						<option value="">All statuses</option>
						{availableStatuses.map((status) => (
							<option key={status} value={status}>
								{status}
							</option>
						))}
					</select>

					<select
						value={priorityFilter}
						onChange={(event) => handlePriorityChange(event.target.value as "" | SearchPriorityFilter)}
						className="min-w-[160px] py-2 px-3 text-sm border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-stone-500 dark:focus:ring-stone-400 transition-colors duration-200"
					>
						{PRIORITY_OPTIONS.map((option) => (
							<option key={option.value || "all"} value={option.value}>
								{option.label}
							</option>
						))}
					</select>

					{/* Do Today Toggle */}
					<button
						type="button"
						onClick={handleDoTodayToggle}
						className={`py-2 px-3 text-sm border rounded-lg transition-colors duration-200 cursor-pointer flex items-center gap-1.5 ${
							doTodayFilter
								? 'border-amber-400 bg-amber-50 dark:bg-amber-900/30 text-amber-700 dark:text-amber-300 hover:bg-amber-100 dark:hover:bg-amber-900/50'
								: 'border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 hover:bg-gray-100 dark:hover:bg-gray-700'
						}`}
						title={doTodayFilter ? 'Showing Do Today tasks only' : 'Show Do Today tasks only'}
					>
						<svg className="w-4 h-4" viewBox="0 0 24 24" fill={doTodayFilter ? 'currentColor' : 'none'} stroke="currentColor" strokeWidth={2}>
							<path strokeLinecap="round" strokeLinejoin="round" d="M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z" />
						</svg>
						Today
					</button>

					{/* Active Label Filters */}
					{labelFilters.length > 0 && (
						<div className="flex items-center gap-1 flex-wrap">
							{labelFilters.map(label => (
								<button
									key={label}
									type="button"
									onClick={() => handleLabelToggle(label)}
									className="px-2 py-1 text-xs bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors duration-200 cursor-pointer flex items-center gap-1"
								>
									{label}
									<span>×</span>
								</button>
							))}
						</div>
					)}

					{statusFilter.toLowerCase() === 'done' && displayTasks.length > 0 && (
						<button
							type="button"
							onClick={() => setShowCleanupModal(true)}
							className="py-2 px-3 text-sm border border-gray-300 dark:border-gray-600 rounded-lg text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors duration-200 cursor-pointer flex items-center gap-2"
							title="Clean up old completed tasks"
						>
							<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
								<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
							</svg>
							Clean Up
						</button>
					)}

					{hasActiveFilters && (
						<button
							type="button"
							onClick={handleClearFilters}
							className="py-2 px-3 text-sm border border-gray-300 dark:border-gray-600 rounded-lg text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors duration-200 cursor-pointer"
						>
							Clear filters
						</button>
					)}

					<div className="ml-auto text-sm text-gray-600 dark:text-gray-300">
						Showing {currentCount} of {totalTasks} tasks
					</div>
				</div>

				{error && (
					<div className="rounded-lg border border-red-200 dark:border-red-800 bg-red-50 dark:bg-red-900/20 px-3 py-2 text-sm text-red-700 dark:text-red-300">
						{error}
					</div>
				)}
			</div>

			{displayTasks.length === 0 ? (
				<div className="text-center py-12">
					<svg className="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
						<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
					</svg>
					<h3 className="mt-2 text-sm font-medium text-gray-900 dark:text-white">
						{hasActiveFilters ? "No tasks match the current filters" : "No tasks"}
					</h3>
					<p className="mt-1 text-sm text-gray-500 dark:text-gray-400">
						{hasActiveFilters
							? "Try adjusting your search or clearing filters to see more tasks."
							: "Get started by creating a new task."}
					</p>
				</div>
			) : (
				<div className="space-y-4">
					{displayTasks.map((task) => {
						const isFromOtherBranch = Boolean(task.branch);
						return (
						<div
							key={task.id}
							className={`bg-white dark:bg-gray-800 border rounded-lg p-4 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors duration-200 cursor-pointer ${
								isFromOtherBranch 
									? 'border-amber-300 dark:border-amber-700 opacity-75' 
									: 'border-gray-200 dark:border-gray-700'
							}`}
							onClick={() => onEditTask(task)}
						>
							{/* Cross-branch indicator banner */}
							{isFromOtherBranch && (
								<div className="flex items-center gap-1.5 mb-3 px-2 py-1.5 -mx-1 -mt-1 bg-amber-50 dark:bg-amber-900/30 border-b border-amber-200 dark:border-amber-700 rounded-t text-xs text-amber-700 dark:text-amber-300">
									<svg className="w-3.5 h-3.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
										<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
									</svg>
									<span>
										Read-only: From <span className="font-semibold">{task.branch}</span> branch
									</span>
								</div>
							)}
							<div className="flex items-start justify-between">
								<div className="flex-1">
									<div className="flex items-center space-x-3 mb-2">
										{/* Do Today Star */}
										{onUpdateTask && !isFromOtherBranch && (
											<button
												onClick={(e) => {
													e.stopPropagation();
													handleToggleDoToday(task.id, !task.doToday);
												}}
												className={`p-0.5 rounded transition-colors duration-150 cursor-pointer ${
													task.doToday
														? 'text-amber-500 hover:text-amber-600'
														: 'text-gray-300 dark:text-gray-500 hover:text-amber-400 dark:hover:text-amber-400'
												}`}
												title={task.doToday ? 'Remove from Do Today' : 'Add to Do Today'}
											>
												<svg className="w-5 h-5" viewBox="0 0 24 24" fill={task.doToday ? 'currentColor' : 'none'} stroke="currentColor" strokeWidth={2}>
													<path strokeLinecap="round" strokeLinejoin="round" d="M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z" />
												</svg>
											</button>
										)}
										{/* Read-only star for doToday from other branch */}
										{task.doToday && isFromOtherBranch && (
											<span className="p-0.5 text-amber-500">
												<svg className="w-5 h-5" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" strokeWidth={2}>
													<path strokeLinecap="round" strokeLinejoin="round" d="M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z" />
												</svg>
											</span>
										)}
										<h3 className={`text-lg font-medium ${isFromOtherBranch ? 'text-gray-600 dark:text-gray-400' : 'text-gray-900 dark:text-white'}`}>{task.title}</h3>
										<span className={`px-2 py-1 text-xs font-medium rounded-circle ${getStatusColor(task.status)}`}>
											{task.status}
										</span>
										{task.priority && (
											<span className={`px-2 py-1 text-xs font-medium rounded-circle ${getPriorityColor(task.priority)}`}>
												{task.priority}
											</span>
										)}
									</div>
									<div className="flex items-center space-x-4 text-sm text-gray-500 dark:text-gray-400 mb-2">
										<span>{task.id}</span>
										<span>Created: {new Date(task.createdDate).toLocaleDateString()}</span>
										{task.updatedDate && (
											<span>Updated: {new Date(task.updatedDate).toLocaleDateString()}</span>
										)}
									</div>
									{task.assignee && task.assignee.length > 0 && (
										<div className="flex items-center space-x-2 mb-2">
											<span className="text-sm text-gray-500 dark:text-gray-400">Assigned to:</span>
											<div className="flex flex-wrap gap-1">
												{task.assignee.map((person) => (
													<span key={person} className="px-2 py-1 text-xs bg-blue-100 text-blue-800 dark:bg-blue-900/50 dark:text-blue-200 rounded-circle">
														{person}
													</span>
												))}
											</div>
										</div>
									)}
									{task.labels && task.labels.length > 0 && (
										<div className="flex flex-wrap gap-1">
											{task.labels.map((label) => {
												const isActive = labelFilters.includes(label);
												return (
													<button
														key={label}
														onClick={(e) => {
															e.stopPropagation();
															handleLabelToggle(label);
														}}
														className={`px-2 py-1 text-xs rounded-circle transition-colors duration-200 cursor-pointer ${
															isActive
																? 'bg-blue-500 text-white hover:bg-blue-600'
																: 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-200 hover:bg-blue-100 dark:hover:bg-blue-900/50 hover:text-blue-700 dark:hover:text-blue-300'
														}`}
														title={isActive ? `Remove "${label}" filter` : `Filter by "${label}"`}
													>
														{label}
														{isActive && <span className="ml-1">×</span>}
													</button>
												);
											})}
										</div>
									)}
								</div>
							</div>
						</div>
					)})}
				</div>
			)}

			{/* Cleanup Modal */}
			<CleanupModal
				isOpen={showCleanupModal}
				onClose={() => setShowCleanupModal(false)}
				onSuccess={handleCleanupSuccess}
			/>

			{/* Cleanup Success Toast */}
			{cleanupSuccessMessage && (
				<SuccessToast
					message={cleanupSuccessMessage}
					onDismiss={() => setCleanupSuccessMessage(null)}
					icon={
						<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
							<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
						</svg>
					}
				/>
			)}
		</div>
	);
};

export default TaskList;
