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',
};

const scrollClass =
  '[scrollbar-width:thin] [scrollbar-color:rgba(59,130,246,0.45)_transparent] [&::-webkit-scrollbar]:h-2 [&::-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';

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 min-h-full flex-col">
      <div className="mb-5 flex flex-wrap items-start justify-between gap-4 rounded-3xl border border-white/10 bg-white/[0.025] px-5 py-4">
        <div className="min-w-0">
          <h2 className="text-3xl font-black tracking-tight text-white">
            Registos de Atividade
          </h2>

          <p className="mt-1 max-w-2xl text-sm leading-6 text-slate-400">
            Histórico local de auditoria de provisionamento para técnicos.
          </p>
        </div>

        <div className="flex flex-wrap 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 gap-4 xl:grid-cols-12">
          <div className="xl: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="shrink-0 text-slate-500"
              />

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

          <div className="grid gap-4 sm:grid-cols-2 xl:col-span-6">
            <div>
              <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>
              <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>
        </div>
      </Card>

      <Card className="relative z-10 flex h-[520px] flex-col overflow-hidden">
        <div className="mb-4 flex flex-wrap items-center justify-between gap-3">
          <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-auto rounded-xl border border-white/10 ${scrollClass}`}
        >
          <table className="min-w-[920px] 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-[135px] px-4 py-3">
                  Hora
                </th>

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

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

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

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

                <th className="w-[135px] px-4 py-3">
                  Router
                </th>

                <th className="w-[130px] 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,
                    ).toLocaleTimeString()}
                  </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-semibold text-white">
                    {log.action}
                  </td>

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

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

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

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