"use client";

import { useEffect, useState, useCallback } from 'react';
import api from '../../../lib/api';
import { useRouter } from 'next/navigation';
import {
    ClockIcon,
    UserIcon,
    ShieldExclamationIcon,
    DocumentTextIcon,
    ComputerDesktopIcon,
    ArrowPathIcon,
    ArrowDownTrayIcon,
    MagnifyingGlassIcon,
} from '@heroicons/react/24/outline';

interface AuditLog {
    id: number;
    user_id: number | null;
    username: string;
    event_type: string;
    event_description: string;
    ip_address: string;
    resource_type: string;
    resource_id: string;
    timestamp: string;
}

type SortKey = 'timestamp' | 'user_id' | 'event_type' | 'resource_type' | 'ip_address';
const PAGE_SIZES = [25, 50, 100, 250];

// column header → sort key (null = not sortable)
const COLUMNS: { label: string; key: SortKey | null }[] = [
    { label: 'Time', key: 'timestamp' },
    { label: 'User', key: 'user_id' },
    { label: 'Event', key: 'event_type' },
    { label: 'Description', key: null },
    { label: 'Resource', key: 'resource_type' },
    { label: 'IP', key: 'ip_address' },
];

export default function AuditLogsPage() {
    const [logs, setLogs] = useState<AuditLog[]>([]);
    const [loading, setLoading] = useState(true);
    const [total, setTotal] = useState(0);
    const [page, setPage] = useState(0);            // 0-indexed
    const [pageSize, setPageSize] = useState(100);
    const [search, setSearch] = useState('');
    const [searchInput, setSearchInput] = useState('');
    const [sort, setSort] = useState<SortKey>('timestamp');
    const [order, setOrder] = useState<'asc' | 'desc'>('desc');
    const router = useRouter();

    const fetchLogs = useCallback(async () => {
        setLoading(true);
        try {
            const res = await api.get('/audit/logs', {
                params: { skip: page * pageSize, limit: pageSize, search: search || undefined, sort, order },
            });
            setLogs(Array.isArray(res.data) ? res.data : []);
            const t = parseInt(res.headers['x-total-count'] ?? '0', 10);
            setTotal(Number.isNaN(t) ? 0 : t);
        } catch (error: any) {
            console.error('Failed to fetch logs', error);
            if (error.response?.status === 403) router.push('/');
        } finally {
            setLoading(false);
        }
    }, [page, pageSize, search, sort, order, router]);

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

    // Debounce the search box → commit to `search` (which resets to page 0).
    useEffect(() => {
        const id = setTimeout(() => { setPage(0); setSearch(searchInput.trim()); }, 400);
        return () => clearTimeout(id);
    }, [searchInput]);

    const toggleSort = (key: SortKey | null) => {
        if (!key) return;
        if (sort === key) {
            setOrder(o => (o === 'asc' ? 'desc' : 'asc'));
        } else {
            setSort(key);
            setOrder('desc');
        }
        setPage(0);
    };

    const getEventIcon = (type: string) => {
        if (type.includes('login') || type.includes('logout')) return <UserIcon className="h-4 w-4 text-blue-500" />;
        if (type.includes('security') || type.includes('alert')) return <ShieldExclamationIcon className="h-4 w-4 text-red-500" />;
        if (type.includes('scan')) return <ArrowPathIcon className="h-4 w-4 text-green-500" />;
        if (type.includes('asset')) return <ComputerDesktopIcon className="h-4 w-4 text-purple-500" />;
        return <DocumentTextIcon className="h-4 w-4 text-gray-500" />;
    };

    const formatDate = (dateStr: string) => new Date(dateStr).toLocaleString();

    const totalPages = Math.max(1, Math.ceil(total / pageSize));
    const from = total === 0 ? 0 : page * pageSize + 1;
    const to = Math.min((page + 1) * pageSize, total);

    return (
        <div className="space-y-6">
            <div className="flex flex-wrap justify-between items-center gap-3">
                <h1 className="text-2xl font-bold text-gray-900 tracking-tight font-mono">
                    Audit Logs
                    <span className="ml-2 text-sm font-normal text-gray-500 bg-gray-100 px-2 py-0.5 rounded-full">
                        {total.toLocaleString()} events
                    </span>
                </h1>
                <div className="flex items-center gap-2">
                    <div className="relative">
                        <MagnifyingGlassIcon className="h-4 w-4 text-gray-400 absolute left-2.5 top-1/2 -translate-y-1/2" />
                        <input
                            type="text"
                            value={searchInput}
                            onChange={(e) => setSearchInput(e.target.value)}
                            placeholder="Search description, event, resource, IP, user…"
                            className="w-72 rounded-md border-gray-300 pl-8 pr-3 h-9 text-sm font-mono focus:border-truevuln-blue focus:ring-truevuln-blue"
                        />
                    </div>
                    <a
                        href="/audit/logs/export"
                        className="inline-flex items-center gap-1 p-2 text-gray-600 hover:text-gray-900 hover:bg-gray-100 rounded-lg transition-colors text-sm font-mono"
                        title="Export full audit log as CSV (admin)"
                    >
                        <ArrowDownTrayIcon className="h-5 w-5" /> CSV
                    </a>
                    <button
                        onClick={() => fetchLogs()}
                        className="p-2 text-gray-500 hover:text-gray-700 hover:bg-gray-100 rounded-lg transition-colors"
                        title="Refresh Logs"
                    >
                        <ArrowPathIcon className="h-5 w-5" />
                    </button>
                </div>
            </div>

            <div className="bg-white border border-gray-200 shadow-sm rounded-lg overflow-hidden">
                <div className="overflow-x-auto">
                    <table className="min-w-full divide-y divide-gray-200">
                        <thead className="bg-gray-50">
                            <tr>
                                {COLUMNS.map((c) => (
                                    <th
                                        key={c.label}
                                        onClick={() => toggleSort(c.key)}
                                        className={`px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider font-mono select-none ${c.key ? 'cursor-pointer hover:text-gray-700' : ''}`}
                                    >
                                        {c.label}
                                        {c.key && sort === c.key && <span className="ml-1">{order === 'asc' ? '▲' : '▼'}</span>}
                                    </th>
                                ))}
                            </tr>
                        </thead>
                        <tbody className="bg-white divide-y divide-gray-200 font-mono text-sm">
                            {loading ? (
                                <tr><td colSpan={6} className="px-6 py-12 text-center text-gray-500">Loading…</td></tr>
                            ) : logs.length === 0 ? (
                                <tr><td colSpan={6} className="px-6 py-12 text-center text-gray-500">No audit logs found.</td></tr>
                            ) : logs.map((log) => (
                                <tr key={log.id} className="hover:bg-gray-50 transition-colors">
                                    <td className="px-6 py-4 whitespace-nowrap text-gray-500">
                                        <div className="flex items-center gap-2">
                                            <ClockIcon className="h-3 w-3" />
                                            {formatDate(log.timestamp)}
                                        </div>
                                    </td>
                                    <td className="px-6 py-4 whitespace-nowrap">
                                        <span className={`px-2 py-0.5 rounded-full text-xs font-medium ${log.username === 'System/Deleted' ? 'bg-gray-100 text-gray-600' : 'bg-blue-50 text-blue-700'}`}>
                                            {log.username}
                                        </span>
                                    </td>
                                    <td className="px-6 py-4 whitespace-nowrap">
                                        <div className="flex items-center gap-2">
                                            {getEventIcon(log.event_type)}
                                            <span className="capitalize">{log.event_type.replace(/_/g, ' ')}</span>
                                        </div>
                                    </td>
                                    <td className="px-6 py-4 text-gray-900 max-w-xs truncate" title={log.event_description}>
                                        {log.event_description}
                                    </td>
                                    <td className="px-6 py-4 whitespace-nowrap text-gray-500">
                                        {log.resource_type && (
                                            <span className="px-2 py-0.5 bg-gray-100 rounded text-xs">
                                                {log.resource_type} {log.resource_id ? `#${log.resource_id}` : ''}
                                            </span>
                                        )}
                                    </td>
                                    <td className="px-6 py-4 whitespace-nowrap text-gray-500 text-xs">
                                        {log.ip_address || '-'}
                                    </td>
                                </tr>
                            ))}
                        </tbody>
                    </table>
                </div>

                {/* Pagination bar */}
                <div className="border-t border-gray-200 px-4 py-3 flex flex-wrap items-center justify-between gap-3 bg-gray-50 text-sm font-mono text-gray-600">
                    <div className="flex items-center gap-2">
                        <span>Rows per page:</span>
                        <select
                            value={pageSize}
                            onChange={(e) => { setPageSize(parseInt(e.target.value, 10)); setPage(0); }}
                            className="rounded-md border-gray-300 h-8 text-sm py-0"
                        >
                            {PAGE_SIZES.map(s => <option key={s} value={s}>{s}</option>)}
                        </select>
                        <span className="ml-2">{from.toLocaleString()}–{to.toLocaleString()} of {total.toLocaleString()}</span>
                    </div>
                    <div className="flex items-center gap-2">
                        <button
                            disabled={page === 0}
                            onClick={() => setPage(0)}
                            className="px-2 py-1 rounded border border-gray-300 bg-white hover:bg-gray-100 disabled:opacity-40 disabled:cursor-not-allowed"
                        >« First</button>
                        <button
                            disabled={page === 0}
                            onClick={() => setPage(p => Math.max(0, p - 1))}
                            className="px-3 py-1 rounded border border-gray-300 bg-white hover:bg-gray-100 disabled:opacity-40 disabled:cursor-not-allowed"
                        >Prev</button>
                        <span className="px-2">Page {page + 1} of {totalPages.toLocaleString()}</span>
                        <button
                            disabled={page + 1 >= totalPages}
                            onClick={() => setPage(p => p + 1)}
                            className="px-3 py-1 rounded border border-gray-300 bg-white hover:bg-gray-100 disabled:opacity-40 disabled:cursor-not-allowed"
                        >Next</button>
                        <button
                            disabled={page + 1 >= totalPages}
                            onClick={() => setPage(totalPages - 1)}
                            className="px-2 py-1 rounded border border-gray-300 bg-white hover:bg-gray-100 disabled:opacity-40 disabled:cursor-not-allowed"
                        >Last »</button>
                    </div>
                </div>
            </div>
        </div>
    );
}
