import { useEffect, useMemo, useState } from 'react';
import {
    Download,
    Search,
    Trash2,
} from 'lucide-react';

import { Button } from '@/components/ui/Button';
import { Card } from '@/components/ui/Card';
import { Badge } from '@/components/ui/Badge';
import { Select } from '@/components/ui/Select';

import {
    clearActivityLogs,
    exportActivityLogs,
    getActivityLogs,
} from '@/services/activityLogService';

import type {
    ActivityLogEntry,
    ActivityLogLevel,
    ActivityLogSource,
} from '@/types/activity';

const levels: Array<'all' | ActivityLogLevel> = [
    'all',
    'info',
    'success',
    'warning',
    'error',
];

const sources: Array<'all' | ActivityLogSource> = [
    'all',
    'desktop',
    'router',
    'backend',
    'vps',
];

const levelLabels: Record<'all' | ActivityLogLevel, string> = {
    all: 'Todos',
    info: 'Info',
    success: 'Sucesso',
    warning: 'Aviso',
    error: 'Erro',
};

const sourceLabels: Record<'all' | ActivityLogSource, string> = {
    all: 'Todas',
    desktop: 'Desktop',
    router: 'Router',
    backend: 'Backend',
    vps: 'VPS',
};

function levelTone(level: ActivityLogLevel) {
    if (level === 'success') return 'green';
    if (level === 'warning') return 'purple';
    if (level === 'error') return 'red';

    return 'blue';
}

export function ActivityLogs() {
    const [logs, setLogs] = useState<
        ActivityLogEntry[]
    >([]);

    const [levelFilter, setLevelFilter] =
        useState<'all' | ActivityLogLevel>('all');

    const [sourceFilter, setSourceFilter] =
        useState<'all' | ActivityLogSource>('all');

    const [query, setQuery] = useState('');

    function refreshLogs() {
        setLogs(getActivityLogs());
    }

    useEffect(() => {
        refreshLogs();

        window.addEventListener(
            'activity-log-added',
            refreshLogs,
        );

        return () => {
            window.removeEventListener(
                'activity-log-added',
                refreshLogs,
            );
        };
    }, []);

    const filteredLogs = useMemo(() => {
        const normalizedQuery =
            query.trim().toLowerCase();

        return logs.filter((log) => {
            const matchesLevel =
                levelFilter === 'all' ||
                log.level === levelFilter;

            const matchesSource =
                sourceFilter === 'all' ||
                log.source === sourceFilter;

            const matchesQuery =
                !normalizedQuery ||
                [
                    log.action,
                    log.message,
                    log.routerIp,
                    log.vpnIp,
                    log.source,
                    log.level,
                ]
                    .filter(Boolean)
                    .join(' ')
                    .toLowerCase()
                    .includes(normalizedQuery);

            return (
                matchesLevel &&
                matchesSource &&
                matchesQuery
            );
        });
    }, [logs, levelFilter, sourceFilter, query]);

    return (
        <div className="flex h-full flex-col overflow-hidden">
            <div className="mb-5 flex items-center justify-between">
                <div>
                    <h2 className="text-3xl font-bold tracking-tight text-white">
                        Registos de Atividade
                    </h2>

                    <p className="mt-1 text-slate-400">
                        Histórico local de auditoria de
                        provisionamento para técnicos.
                    </p>
                </div>

                <div className="flex items-center gap-3">
                    <Button
                        type="button"
                        variant="secondary"
                        onClick={() => {
                            exportActivityLogs();
                        }}
                    >
                        <Download size={16} />
                        Exportar JSON
                    </Button>

                    <Button
                        type="button"
                        variant="danger"
                        onClick={() => {
                            clearActivityLogs();
                            refreshLogs();
                        }}
                    >
                        <Trash2 size={16} />
                        Limpar Registos
                    </Button>
                </div>
            </div>

            <Card className="relative z-30 mb-4 overflow-visible">
                <div className="grid grid-cols-12 gap-4">
                    <div className="col-span-6">
                        <label className="mb-2 block text-xs font-medium uppercase tracking-wide text-slate-500">
                            Pesquisa
                        </label>

                        <div className="flex items-center gap-2 rounded-xl border border-white/10 bg-ink-950 px-3">
                            <Search
                                size={16}
                                className="text-slate-500"
                            />

                            <input
                                value={query}
                                onChange={(event) =>
                                    setQuery(event.target.value)
                                }
                                placeholder="Pesquisar ação, IP VPN, IP router, mensagem..."
                                className="w-full bg-transparent py-3 text-sm text-white outline-none placeholder:text-slate-600"
                            />
                        </div>
                    </div>

                    <div className="col-span-3">
                        <label className="mb-2 block text-xs font-medium uppercase tracking-wide text-slate-500">
                            Nível
                        </label>

                        <Select
                            value={levelFilter}
                            onChange={setLevelFilter}
                            options={levels.map((level) => ({
                                value: level,
                                label: levelLabels[level],
                            }))}
                        />
                    </div>

                    <div className="col-span-3">
                        <label className="mb-2 block text-xs font-medium uppercase tracking-wide text-slate-500">
                            Origem
                        </label>

                        <Select
                            value={sourceFilter}
                            onChange={setSourceFilter}
                            options={sources.map((source) => ({
                                value: source,
                                label: sourceLabels[source],
                            }))}
                        />
                    </div>
                </div>
            </Card>

            <Card className="relative z-10 flex min-h-0 flex-1 flex-col overflow-hidden">
                <div className="mb-4 flex items-center justify-between">
                    <h3 className="font-semibold text-white">
                        Eventos de Auditoria
                    </h3>

                    <span className="text-sm text-slate-500">
                        {filteredLogs.length} apresentados /{' '}
                        {logs.length} total
                    </span>
                </div>

                <div className="min-h-0 flex-1 overflow-y-auto rounded-xl border border-white/10
                [scrollbar-width:thin]
                [scrollbar-color:rgba(59,130,246,0.45)_transparent]
                [&::-webkit-scrollbar]:w-2
                [&::-webkit-scrollbar-track]:bg-transparent
                [&::-webkit-scrollbar-thumb]:rounded-full
                [&::-webkit-scrollbar-thumb]:bg-blue-500/30
                hover:[&::-webkit-scrollbar-thumb]:bg-blue-500/50">
                    <table className="w-full table-fixed text-sm">
                        <thead className="sticky top-0 z-10 bg-slate-950 text-left text-xs uppercase tracking-wide text-slate-500">
                            <tr>
                                <th className="w-[180px] px-4 py-3">
                                    Hora
                                </th>

                                <th className="w-[110px] px-4 py-3">
                                    Nível
                                </th>

                                <th className="w-[120px] px-4 py-3">
                                    Origem
                                </th>

                                <th className="w-[190px] px-4 py-3">
                                    Ação
                                </th>

                                <th className="px-4 py-3">
                                    Mensagem
                                </th>

                                <th className="w-[160px] px-4 py-3">
                                    IP VPN
                                </th>
                            </tr>
                        </thead>

                        <tbody className="divide-y divide-white/10">
                            {filteredLogs.map((log) => (
                                <tr
                                    key={log.id}
                                    className="bg-white/[0.01] hover:bg-white/[0.04]"
                                >
                                    <td className="px-4 py-3 font-mono text-xs text-slate-400">
                                        {new Date(
                                            log.timestamp,
                                        ).toLocaleString()}
                                    </td>

                                    <td className="px-4 py-3">
                                        <Badge tone={levelTone(log.level)}>
                                            {levelLabels[log.level]}
                                        </Badge>
                                    </td>

                                    <td className="px-4 py-3 text-slate-300">
                                        {sourceLabels[log.source]}
                                    </td>

                                    <td className="truncate px-4 py-3 font-medium text-white">
                                        {log.action}
                                    </td>

                                    <td className="truncate px-4 py-3 text-slate-400">
                                        {log.message}
                                    </td>

                                    <td className="px-4 py-3 font-mono text-slate-300">
                                        {log.vpnIp ?? '—'}
                                    </td>
                                </tr>
                            ))}

                            {filteredLogs.length === 0 && (
                                <tr>
                                    <td
                                        colSpan={6}
                                        className="px-4 py-10 text-center text-slate-500"
                                    >
                                        Nenhum registo de atividade encontrado.
                                    </td>
                                </tr>
                            )}
                        </tbody>
                    </table>
                </div>
            </Card>
        </div>
    );
}