import { useEffect, useState } from '@wordpress/element';
import Layout from '../layout/Layout';
import { getTokenLogs, clearTokenLogs, adminRevokeToken } from '../../api/local';
import { showPromiseToast, showToast } from '../../utils';

const statusOptions = [
    { value: '', label: 'All statuses' },
    { value: 'active', label: 'Active' },
    { value: 'revoked', label: 'Revoked' },
    { value: 'expired', label: 'Expired' },
    { value: 'error', label: 'Error' },
];

const TokenLogs = () => {
    const [logs, setLogs] = useState([]);
    const [filters, setFilters] = useState({ user_id: '', status: '' });
    const [loading, setLoading] = useState(false);

    const loadLogs = () => {
        setLoading(true);
        const res = getTokenLogs({
            user_id: filters.user_id || undefined,
            status: filters.status || undefined,
            per_page: 100,
        }).then((data) => {
            setLogs(data?.logs || []);
            setLoading(false);
        });

        showPromiseToast(res, 'Loading token logs');
    };

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

    const handleFilterSubmit = (e) => {
        e.preventDefault();
        loadLogs();
    };

    const handleClearLogs = () => {
        const res = clearTokenLogs().then(() => loadLogs());
        showPromiseToast(res, 'Clearing logs', 'Logs cleared');
    };

    const handleExport = (type = 'json') => {
        if (!logs.length) {
            showToast('No logs to export');
            return;
        }

        const fileName = `headlesskey-token-logs.${type}`;

        let content = '';
        if (type === 'csv') {
            const headers = Object.keys(logs[0]);
            const rows = logs.map((log) => headers.map((key) => `"${log[key] ?? ''}"`).join(','));
            content = [headers.join(','), ...rows].join('\n');
        } else {
            content = JSON.stringify(logs, null, 2);
        }

        const blob = new Blob([content], { type: 'text/plain;charset=utf-8;' });
        const url = URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.setAttribute('download', fileName);
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
    };

    const handleRevoke = (hash) => {
        const res = adminRevokeToken(hash).then(() => loadLogs());
        showPromiseToast(res, 'Revoking token', 'Token revoked');
    };

    return (
        <Layout>
            <div className="bg-white rounded p-6">
                <div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
                    <div>
                        <h2 className="text-2xl font-bold text-gray-900">Token Logs</h2>
                        <p className="text-gray-600 text-sm mt-1">Audit issued tokens, revoke compromised ones, and export activity.</p>
                    </div>
                    <div className="flex gap-2">
                        <button
                            type="button"
                            className="rounded-md bg-gray-100 px-3 py-2 text-sm font-semibold text-gray-800 shadow-sm hover:bg-gray-200"
                            onClick={() => handleExport('json')}
                        >
                            Export JSON
                        </button>
                        <button
                            type="button"
                            className="rounded-md bg-gray-100 px-3 py-2 text-sm font-semibold text-gray-800 shadow-sm hover:bg-gray-200"
                            onClick={() => handleExport('csv')}
                        >
                            Export CSV
                        </button>
                        <button
                            type="button"
                            className="rounded-md bg-red-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-red-700"
                            onClick={handleClearLogs}
                        >
                            Clear Logs
                        </button>
                    </div>
                </div>

                <form className="mt-6 grid grid-cols-1 md:grid-cols-3 gap-4" onSubmit={handleFilterSubmit}>
                    <div>
                        <label className="block text-sm font-medium text-gray-700">Filter by User ID</label>
                        <input
                            type="number"
                            className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-gray-500 focus:ring-gray-500"
                            value={filters.user_id}
                            onChange={(e) => setFilters({ ...filters, user_id: e.target.value })}
                            placeholder="e.g. 1"
                        />
                    </div>
                    <div>
                        <label className="block text-sm font-medium text-gray-700">Status</label>
                        <select
                            className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-gray-500 focus:ring-gray-500"
                            value={filters.status}
                            onChange={(e) => setFilters({ ...filters, status: e.target.value })}
                        >
                            {statusOptions.map((option) => (
                                <option key={option.value} value={option.value}>
                                    {option.label}
                                </option>
                            ))}
                        </select>
                    </div>
                    <div className="flex items-end">
                        <button
                            type="submit"
                            className="w-full rounded-md bg-gray-800 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-gray-900"
                        >
                            Apply Filters
                        </button>
                    </div>
                </form>

                <div className="mt-6 overflow-x-auto">
                    <table className="min-w-full divide-y divide-gray-200">
                        <thead className="bg-gray-50">
                        <tr>
                            <th className="px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase">User</th>
                            <th className="px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase">Status</th>
                            <th className="px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase">Issued</th>
                            <th className="px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase">Expires</th>
                            <th className="px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase">IP</th>
                            <th className="px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase">Device</th>
                            <th className="px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase">Actions</th>
                        </tr>
                        </thead>
                        <tbody className="divide-y divide-gray-200 bg-white">
                        {!loading && logs.map((log) => (
                            <tr key={log.id}>
                                <td className="px-3 py-3 text-sm text-gray-900">
                                    #{log.user_id}
                                    <div className="text-xs text-gray-500">{log.token_jti}</div>
                                </td>
                                <td className="px-3 py-3 text-sm">
                                    <span
                                        className={`inline-flex rounded-full px-2 text-xs font-semibold leading-5 ${
                                            log.status === 'active'
                                                ? 'bg-green-100 text-green-800'
                                                : log.status === 'revoked'
                                                    ? 'bg-red-100 text-red-800'
                                                    : 'bg-gray-100 text-gray-800'
                                        }`}
                                    >
                                        {log.status}
                                    </span>
                                </td>
                                <td className="px-3 py-3 text-sm text-gray-500">{log.issued_at}</td>
                                <td className="px-3 py-3 text-sm text-gray-500">{log.expires_at}</td>
                                <td className="px-3 py-3 text-sm text-gray-500">{log.ip_address}</td>
                                <td className="px-3 py-3 text-sm text-gray-500 break-words">{log.device}</td>
                                <td className="px-3 py-3 text-sm">
                                    {log.status === 'active' && (
                                        <button
                                            type="button"
                                            className="text-red-600 hover:text-red-800 text-sm font-medium"
                                            onClick={() => handleRevoke(log.token_hash)}
                                        >
                                            Revoke
                                        </button>
                                    )}
                                </td>
                            </tr>
                        ))}
                        {loading && (
                            <tr>
                                <td colSpan="7" className="px-3 py-6 text-center text-sm text-gray-500">
                                    Loading token logs...
                                </td>
                            </tr>
                        )}
                        {!loading && !logs.length && (
                            <tr>
                                <td colSpan="7" className="px-3 py-6 text-center text-sm text-gray-500">
                                    No token logs found.
                                </td>
                            </tr>
                        )}
                        </tbody>
                    </table>
                </div>
            </div>
        </Layout>
    );
};

export default TokenLogs;

