import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { __ } from '@wordpress/i18n';
import { AlertTriangle, Info, RefreshCw, Trash2, XCircle } from 'lucide-react';
import { useState } from 'react';
import { toast } from 'sonner';
import { logsApi, type LogEntry } from '@/admin/api/logs';
import { logsQuery } from '@/admin/queries/logs';
import {
	AlertDialog,
	AlertDialogAction,
	AlertDialogCancel,
	AlertDialogContent,
	AlertDialogDescription,
	AlertDialogFooter,
	AlertDialogHeader,
	AlertDialogTitle,
	AlertDialogTrigger,
} from '@/components/ui/alert-dialog';
import { Button } from '@/components/ui/button';
import { cn } from '@/lib/utils';

const PAGE_SIZE = 20;

const LEVEL_CONFIG: Record<string, { label: string; className: string; iconColor: string; icon: React.ComponentType<{ className?: string }> }> = {
	ERROR:    { label: 'Error',    className: 'bg-red-100 text-red-700 border-red-200',       iconColor: 'text-red-500',    icon: XCircle },
	CRITICAL: { label: 'Critical', className: 'bg-red-100 text-red-700 border-red-200',       iconColor: 'text-red-500',    icon: XCircle },
	WARNING:  { label: 'Warning',  className: 'bg-yellow-100 text-yellow-700 border-yellow-200', iconColor: 'text-yellow-500', icon: AlertTriangle },
	INFO:     { label: 'Info',     className: 'bg-blue-100 text-blue-700 border-blue-200',    iconColor: 'text-blue-500',   icon: Info },
	DEBUG:    { label: 'Debug',    className: 'bg-gray-100 text-gray-600 border-gray-200',    iconColor: 'text-gray-400',   icon: Info },
};

const LEVELS = ['ALL', 'ERROR', 'WARNING', 'INFO', 'DEBUG'] as const;
type LevelFilter = (typeof LEVELS)[number];

const LogRow = ({ entry }: { entry: LogEntry }) => {
	const [expanded, setExpanded] = useState(false);
	const config = LEVEL_CONFIG[entry.level] ?? LEVEL_CONFIG.DEBUG;
	const Icon = config.icon;

	return (
		<div
			className={cn(
				'border-b border-gray-100 px-4 py-2.5 last:border-0',
				entry.context ? 'cursor-pointer hover:bg-gray-50' : '',
			)}
			onClick={() => entry.context && setExpanded((p) => !p)}
		>
			<div className="flex items-start gap-3">
				<Icon className={cn('mt-0.5 size-3.5 shrink-0', config.iconColor)} />
				<div className="min-w-0 flex-1">
					<div className="flex flex-wrap items-center gap-2">
						<span className={cn('inline-flex items-center rounded border px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wide', config.className)}>
							{config.label}
						</span>
						{entry.timestamp && (
							<span className="font-mono text-[11px] text-gray-400">
								{entry.timestamp}
							</span>
						)}
					</div>
					<p className="mt-1 break-all font-mono text-xs text-gray-800">{entry.message}</p>
					{expanded && entry.context && (
						<pre className="mt-2 overflow-x-auto rounded bg-gray-50 p-2 font-mono text-[11px] text-gray-600">
							{JSON.stringify(entry.context, null, 2)}
						</pre>
					)}
				</div>
			</div>
		</div>
	);
};

const LogsSettings = () => {
	const queryClient = useQueryClient();
	const [levelFilter, setLevelFilter] = useState<LevelFilter>('ALL');
	const [visibleCount, setVisibleCount] = useState(PAGE_SIZE);

	const { data, isLoading, isFetching } = useQuery(logsQuery());

	const clearMutation = useMutation({
		mutationFn: logsApi.clear,
		onSuccess: () => {
			queryClient.invalidateQueries({ queryKey: ['logs'] });
			toast.success(__('Logs cleared.', 'allcoach'));
		},
		onError: () => toast.error(__('Failed to clear logs.', 'allcoach')),
	});

	const handleRefresh = async () => {
		await queryClient.invalidateQueries({ queryKey: ['logs'] });
		toast.success(__('Logs refreshed.', 'allcoach'));
	};

	const logs = data?.logs ?? [];
	const stats = data?.stats;

	const filtered = [...(levelFilter === 'ALL' ? logs : logs.filter((l) => l.level === levelFilter))].reverse();
	const visible = filtered.slice(0, visibleCount);
	const hasMore = visibleCount < filtered.length;

	const handleLevelChange = (level: LevelFilter) => {
		setLevelFilter(level);
		setVisibleCount(PAGE_SIZE);
	};

	return (
		<div className="p-6">
			<div className="mb-5 flex flex-wrap items-center justify-between gap-3">
				<div>
					<h2 className="text-sm font-semibold text-gray-900">
						{__('Activity Logs', 'allcoach')}
					</h2>
					{stats && (
						<p className="mt-0.5 text-xs text-gray-500">
							{stats.total_files}{' '}
							{stats.total_files === 1 ? __('file', 'allcoach') : __('files', 'allcoach')}
							{' · '}
							{stats.total_size_formatted}
						</p>
					)}
				</div>
				<div className="flex items-center gap-2">
					<Button
						variant="outline"
						size="sm"
						onClick={handleRefresh}
						disabled={isFetching}
					>
						<RefreshCw className={cn('size-3.5', isFetching && 'animate-spin')} />
						{__('Refresh', 'allcoach')}
					</Button>
					<AlertDialog>
						<AlertDialogTrigger asChild>
							<Button
								variant="outline"
								size="sm"
								className="text-red-600 hover:border-red-300 hover:bg-red-50 hover:text-red-600"
								disabled={clearMutation.isPending || logs.length === 0}
							>
								<Trash2 className="size-3.5" />
								{__('Clear Logs', 'allcoach')}
							</Button>
						</AlertDialogTrigger>
						<AlertDialogContent>
							<AlertDialogHeader>
								<AlertDialogTitle>{__('Clear all logs?', 'allcoach')}</AlertDialogTitle>
								<AlertDialogDescription>
									{__('This will permanently delete all log files. This action cannot be undone.', 'allcoach')}
								</AlertDialogDescription>
							</AlertDialogHeader>
							<AlertDialogFooter>
								<AlertDialogCancel>{__('Cancel', 'allcoach')}</AlertDialogCancel>
								<AlertDialogAction
									className="bg-red-600 hover:bg-red-700"
									onClick={() => clearMutation.mutate()}
								>
									{__('Clear Logs', 'allcoach')}
								</AlertDialogAction>
							</AlertDialogFooter>
						</AlertDialogContent>
					</AlertDialog>
				</div>
			</div>

			{/* Level filters */}
			<div className="mb-4 flex flex-wrap gap-1.5">
				{LEVELS.map((level) => {
					const count = level === 'ALL' ? logs.length : logs.filter((l) => l.level === level).length;
					return (
						<button
							key={level}
							type="button"
							onClick={() => handleLevelChange(level)}
							className={cn(
								'rounded-full border px-2.5 py-1 text-[11px] font-medium transition-colors',
								levelFilter === level
									? 'border-teal-300 bg-teal-50 text-teal-700'
									: 'border-gray-200 bg-white text-gray-600 hover:border-gray-300 hover:bg-gray-50',
							)}
						>
							{level === 'ALL' ? __('All', 'allcoach') : level}{' '}
							<span className="opacity-60">{count}</span>
						</button>
					);
				})}
			</div>

			{/* Log list */}
			<div className="overflow-hidden rounded-lg border border-gray-200 bg-white">
				{isLoading ? (
					<div>
						{Array.from({ length: 8 }).map((_, i) => (
							<div key={i} className="flex gap-3 border-b border-gray-100 px-4 py-2.5">
								<div className="mt-0.5 size-3.5 shrink-0 animate-pulse rounded-full bg-gray-200" />
								<div className="flex-1 space-y-1.5">
									<div className="h-3.5 w-32 animate-pulse rounded bg-gray-100" />
									<div className="h-3 w-full animate-pulse rounded bg-gray-100" />
								</div>
							</div>
						))}
					</div>
				) : filtered.length === 0 ? (
					<div className="py-12 text-center text-sm text-gray-400">
						{logs.length === 0
							? __('No logs found.', 'allcoach')
							: __('No entries match the selected filter.', 'allcoach')}
					</div>
				) : (
					<div className="divide-y divide-gray-100">
						{visible.map((entry, i) => (
							<LogRow key={i} entry={entry} />
						))}
					</div>
				)}
			</div>

			{/* Load more + count */}
			<div className="mt-3 flex items-center justify-between">
				<div>
					{hasMore && (
						<Button
							variant="outline"
							size="sm"
							onClick={() => setVisibleCount((c) => c + PAGE_SIZE)}
						>
							{__('Load More', 'allcoach')}
						</Button>
					)}
				</div>
				{filtered.length > 0 && (
					<p className="text-[11px] text-gray-400">
						{__('Showing', 'allcoach')} {Math.min(visibleCount, filtered.length)} / {filtered.length}
						{filtered.length !== logs.length && ` (${logs.length} ${__('total', 'allcoach')})`}
					</p>
				)}
			</div>
		</div>
	);
};

export default LogsSettings;
