'use client';

import { useState, useEffect, useMemo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { apiClient } from '@/infrastructure/api/api-client';
import { queryKeys } from '@/infrastructure/api/query-keys';
import { cn } from '@/lib/utils';

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

interface MetricsOverview {
  totalServers: number;
  onlinePercent: number;
  avgCpuPercent: number;
  avgMemoryPercent: number;
  totalAlertsToday: number;
}

interface ServerMetric {
  id: string;
  hostname: string;
  environment: 'dev' | 'staging' | 'prod';
  status: 'online' | 'offline';
  cpuPercent: number;
  memoryPercent: number;
  diskPercent: number;
  lastCheckedAt: string;
}

type MetricsOverviewResponse = MetricsOverview;

type ServerMetricsResponse = ServerMetric[];

type EnvironmentFilter = 'all' | 'dev' | 'staging' | 'prod';
type StatusFilter = 'all' | 'online' | 'offline';
type SortField = 'hostname' | 'status' | 'cpuPercent' | 'memoryPercent' | 'diskPercent' | 'lastCheckedAt';
type SortDirection = 'asc' | 'desc';

// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------

const ENV_FILTERS: { labelKey: string; value: EnvironmentFilter }[] = [
  { labelKey: 'metrics.filters.all', value: 'all' },
  { labelKey: 'metrics.filters.dev', value: 'dev' },
  { labelKey: 'metrics.filters.staging', value: 'staging' },
  { labelKey: 'metrics.filters.prod', value: 'prod' },
];

const STATUS_FILTERS: { labelKey: string; value: StatusFilter }[] = [
  { labelKey: 'metrics.filters.all', value: 'all' },
  { labelKey: 'metrics.filters.online', value: 'online' },
  { labelKey: 'metrics.filters.offline', value: 'offline' },
];

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

function formatRelativeTime(dateStr: string): string {
  try {
    const diff = Date.now() - new Date(dateStr).getTime();
    const seconds = Math.floor(diff / 1000);
    if (seconds < 0) return 'just now';
    if (seconds < 60) return `${seconds}s ago`;
    const minutes = Math.floor(seconds / 60);
    if (minutes < 60) return `${minutes}m ago`;
    const hours = Math.floor(minutes / 60);
    if (hours < 24) return `${hours}h ago`;
    const days = Math.floor(hours / 24);
    return `${days}d ago`;
  } catch {
    return dateStr;
  }
}

function getPercentColor(value: number): string {
  if (value < 60) return 'text-green-600 dark:text-green-400';
  if (value < 85) return 'text-yellow-600 dark:text-yellow-400';
  return 'text-red-600 dark:text-red-400';
}

function getPercentBarColor(value: number): string {
  if (value < 60) return 'bg-green-500';
  if (value < 85) return 'bg-yellow-500';
  return 'bg-red-500';
}

// ---------------------------------------------------------------------------
// Overview stat card
// ---------------------------------------------------------------------------

function OverviewCard({
  label,
  value,
  suffix,
  color,
}: {
  label: string;
  value: string | number;
  suffix?: string;
  color?: string;
}) {
  return (
    <div className="bg-card border rounded-lg p-4">
      <p className="text-sm text-muted-foreground mb-1">{label}</p>
      <p className={cn('text-2xl font-bold', color)}>
        {value}
        {suffix && <span className="text-sm font-normal text-muted-foreground ml-1">{suffix}</span>}
      </p>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Status badge
// ---------------------------------------------------------------------------

function StatusBadge({ status }: { status: ServerMetric['status'] }) {
  const styles: Record<ServerMetric['status'], string> = {
    online: 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400',
    offline: 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400',
  };

  return (
    <span
      className={cn(
        'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium capitalize',
        styles[status],
      )}
    >
      {status}
    </span>
  );
}

// ---------------------------------------------------------------------------
// Environment badge
// ---------------------------------------------------------------------------

function EnvironmentBadge({ env }: { env: ServerMetric['environment'] }) {
  const styles: Record<ServerMetric['environment'], string> = {
    dev: 'bg-gray-100 text-gray-800 dark:bg-gray-800/40 dark:text-gray-300',
    staging: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400',
    prod: 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-400',
  };

  return (
    <span
      className={cn(
        'inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium',
        styles[env],
      )}
    >
      {env}
    </span>
  );
}

// ---------------------------------------------------------------------------
// Percent bar
// ---------------------------------------------------------------------------

function PercentBar({ value, label }: { value: number | null | undefined; label?: string }) {
  const v = value ?? 0;
  return (
    <div className="flex items-center gap-2 min-w-[120px]">
      <div className="flex-1 h-2 bg-muted rounded-full overflow-hidden">
        <div
          className={cn('h-full rounded-full transition-all', getPercentBarColor(v))}
          style={{ width: `${Math.min(v, 100)}%` }}
        />
      </div>
      <span className={cn('text-xs font-medium tabular-nums w-10 text-right', getPercentColor(v))}>
        {v.toFixed(1)}%
      </span>
      {label && <span className="text-xs text-muted-foreground">{label}</span>}
    </div>
  );
}

// ---------------------------------------------------------------------------
// Sortable column header
// ---------------------------------------------------------------------------

function SortableHeader({
  label,
  field,
  currentSort,
  currentDirection,
  onSort,
  align,
}: {
  label: string;
  field: SortField;
  currentSort: SortField;
  currentDirection: SortDirection;
  onSort: (field: SortField) => void;
  align?: 'left' | 'right';
}) {
  const isActive = currentSort === field;
  return (
    <th
      className={cn(
        'px-4 py-3 font-medium cursor-pointer select-none hover:text-foreground transition-colors',
        align === 'right' ? 'text-right' : 'text-left',
      )}
      onClick={() => onSort(field)}
    >
      <span className="inline-flex items-center gap-1">
        {label}
        {isActive && (
          <span className="text-xs">
            {currentDirection === 'asc' ? '\u2191' : '\u2193'}
          </span>
        )}
      </span>
    </th>
  );
}

// ---------------------------------------------------------------------------
// Main page component
// ---------------------------------------------------------------------------

export default function MetricsPage() {
  const { t } = useTranslation('monitoring');
  const queryClient = useQueryClient();

  // State ----------------------------------------------------------------
  const [envFilter, setEnvFilter] = useState<EnvironmentFilter>('all');
  const [statusFilter, setStatusFilter] = useState<StatusFilter>('all');
  const [search, setSearch] = useState('');
  const [sortField, setSortField] = useState<SortField>('hostname');
  const [sortDirection, setSortDirection] = useState<SortDirection>('asc');
  const [autoRefresh, setAutoRefresh] = useState(false);

  // Queries --------------------------------------------------------------
  const { data: overviewData, isLoading: overviewLoading } = useQuery({
    queryKey: queryKeys.metrics.overview(),
    queryFn: () => apiClient<MetricsOverviewResponse>('/api/v1/monitor/metrics/overview'),
  });

  const overview = overviewData;

  const { data: serversData, isLoading: serversLoading, error } = useQuery({
    queryKey: queryKeys.metrics.servers(),
    queryFn: () => apiClient<ServerMetricsResponse>('/api/v1/monitor/metrics/servers'),
  });

  const allServers = Array.isArray(serversData) ? serversData : [];

  // Auto-refresh ---------------------------------------------------------
  useEffect(() => {
    if (!autoRefresh) return;
    const intervalId = setInterval(() => {
      queryClient.invalidateQueries({ queryKey: queryKeys.metrics.all });
    }, 30_000);
    return () => clearInterval(intervalId);
  }, [autoRefresh, queryClient]);

  // Filter & sort --------------------------------------------------------
  const filteredServers = useMemo(() => {
    let result = allServers;

    if (envFilter !== 'all') {
      result = result.filter((s) => s.environment === envFilter);
    }

    if (statusFilter !== 'all') {
      result = result.filter((s) => s.status === statusFilter);
    }

    if (search.trim()) {
      const q = search.toLowerCase().trim();
      result = result.filter((s) => s.hostname.toLowerCase().includes(q));
    }

    result.sort((a, b) => {
      let cmp = 0;
      switch (sortField) {
        case 'hostname':
          cmp = a.hostname.localeCompare(b.hostname);
          break;
        case 'status':
          cmp = a.status.localeCompare(b.status);
          break;
        case 'cpuPercent':
          cmp = a.cpuPercent - b.cpuPercent;
          break;
        case 'memoryPercent':
          cmp = a.memoryPercent - b.memoryPercent;
          break;
        case 'diskPercent':
          cmp = a.diskPercent - b.diskPercent;
          break;
        case 'lastCheckedAt':
          cmp = new Date(a.lastCheckedAt).getTime() - new Date(b.lastCheckedAt).getTime();
          break;
      }
      return sortDirection === 'asc' ? cmp : -cmp;
    });

    return result;
  }, [allServers, envFilter, statusFilter, search, sortField, sortDirection]);

  // Handlers -------------------------------------------------------------
  const handleSort = useCallback(
    (field: SortField) => {
      if (sortField === field) {
        setSortDirection((prev) => (prev === 'asc' ? 'desc' : 'asc'));
      } else {
        setSortField(field);
        setSortDirection('asc');
      }
    },
    [sortField],
  );

  const isLoading = overviewLoading || serversLoading;

  // Render ---------------------------------------------------------------
  return (
    <div>
      {/* Header */}
      <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-6">
        <div>
          <h1 className="text-2xl font-bold">{t('metrics.title')}</h1>
          <p className="text-sm text-muted-foreground mt-1">
            {t('metrics.subtitle')}
          </p>
        </div>
        <div className="flex items-center gap-3">
          <label className="flex items-center gap-2 text-sm cursor-pointer">
            <input
              type="checkbox"
              checked={autoRefresh}
              onChange={(e) => setAutoRefresh(e.target.checked)}
              className="h-4 w-4 rounded border-input text-primary focus:ring-primary cursor-pointer"
            />
            {t('metrics.autoRefresh')}
          </label>
          {autoRefresh && (
            <span className="flex items-center gap-1.5 text-xs text-muted-foreground">
              <span className="w-1.5 h-1.5 rounded-full bg-green-500 animate-pulse" />
              {t('metrics.live')}
            </span>
          )}
        </div>
      </div>

      {/* Overview cards */}
      {overview && (
        <div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-4 mb-6">
          <OverviewCard
            label={t('metrics.overview.totalServers')}
            value={overview.totalServers}
          />
          <OverviewCard
            label={t('metrics.overview.online')}
            value={`${(overview.onlinePercent ?? 0).toFixed(1)}`}
            suffix="%"
            color={(overview.onlinePercent ?? 0) >= 95 ? 'text-green-600 dark:text-green-400' : 'text-yellow-600 dark:text-yellow-400'}
          />
          <OverviewCard
            label={t('metrics.overview.avgCpu')}
            value={`${(overview.avgCpuPercent ?? 0).toFixed(1)}`}
            suffix="%"
            color={getPercentColor(overview.avgCpuPercent ?? 0)}
          />
          <OverviewCard
            label={t('metrics.overview.avgMemory')}
            value={`${(overview.avgMemoryPercent ?? 0).toFixed(1)}`}
            suffix="%"
            color={getPercentColor(overview.avgMemoryPercent ?? 0)}
          />
          <OverviewCard
            label={t('metrics.overview.alertsToday')}
            value={overview.totalAlertsToday}
            color={overview.totalAlertsToday > 0 ? 'text-red-600 dark:text-red-400' : undefined}
          />
        </div>
      )}

      {overviewLoading && (
        <div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-4 mb-6">
          {Array.from({ length: 5 }).map((_, i) => (
            <div key={i} className="bg-card border rounded-lg p-4 animate-pulse">
              <div className="h-4 bg-muted rounded w-20 mb-2" />
              <div className="h-7 bg-muted rounded w-16" />
            </div>
          ))}
        </div>
      )}

      {/* Filters */}
      <div className="flex flex-col sm:flex-row sm:items-center gap-4 mb-6">
        {/* Search */}
        <div className="flex-1 max-w-sm">
          <input
            type="text"
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            className="w-full px-3 py-2 rounded-md border border-input bg-background text-sm"
            placeholder={t('metrics.searchPlaceholder')}
          />
        </div>

        {/* Environment filter */}
        <div className="flex gap-1 p-1 bg-muted rounded-lg">
          {ENV_FILTERS.map((f) => (
            <button
              key={f.value}
              onClick={() => setEnvFilter(f.value)}
              className={cn(
                'px-3 py-1.5 text-sm rounded-md font-medium transition-colors',
                envFilter === f.value
                  ? 'bg-background text-foreground shadow-sm'
                  : 'text-muted-foreground hover:text-foreground',
              )}
            >
              {t(f.labelKey)}
            </button>
          ))}
        </div>

        {/* Status filter */}
        <div className="flex gap-1 p-1 bg-muted rounded-lg">
          {STATUS_FILTERS.map((f) => (
            <button
              key={f.value}
              onClick={() => setStatusFilter(f.value)}
              className={cn(
                'px-3 py-1.5 text-sm rounded-md font-medium transition-colors',
                statusFilter === f.value
                  ? 'bg-background text-foreground shadow-sm'
                  : 'text-muted-foreground hover:text-foreground',
              )}
            >
              {t(f.labelKey)}
            </button>
          ))}
        </div>
      </div>

      {/* Error state */}
      {error && (
        <div className="p-4 mb-4 rounded-md border border-destructive/50 bg-destructive/10 text-destructive text-sm">
          {t('metrics.loadError')} {(error as Error).message}
        </div>
      )}

      {/* Loading state */}
      {serversLoading && (
        <div className="text-sm text-muted-foreground py-12 text-center">
          {t('metrics.loading')}
        </div>
      )}

      {/* Metrics table */}
      {!serversLoading && !error && (
        <div className="border rounded-lg overflow-hidden">
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b bg-muted/50">
                  <SortableHeader
                    label={t('metrics.table.hostname')}
                    field="hostname"
                    currentSort={sortField}
                    currentDirection={sortDirection}
                    onSort={handleSort}
                  />
                  <th className="text-left px-4 py-3 font-medium">{t('metrics.table.env')}</th>
                  <SortableHeader
                    label={t('metrics.table.status')}
                    field="status"
                    currentSort={sortField}
                    currentDirection={sortDirection}
                    onSort={handleSort}
                  />
                  <SortableHeader
                    label={t('metrics.table.cpuPercent')}
                    field="cpuPercent"
                    currentSort={sortField}
                    currentDirection={sortDirection}
                    onSort={handleSort}
                  />
                  <SortableHeader
                    label={t('metrics.table.memoryPercent')}
                    field="memoryPercent"
                    currentSort={sortField}
                    currentDirection={sortDirection}
                    onSort={handleSort}
                  />
                  <SortableHeader
                    label={t('metrics.table.diskPercent')}
                    field="diskPercent"
                    currentSort={sortField}
                    currentDirection={sortDirection}
                    onSort={handleSort}
                  />
                  <SortableHeader
                    label={t('metrics.table.lastChecked')}
                    field="lastCheckedAt"
                    currentSort={sortField}
                    currentDirection={sortDirection}
                    onSort={handleSort}
                    align="right"
                  />
                </tr>
              </thead>
              <tbody>
                {filteredServers.length === 0 ? (
                  <tr>
                    <td
                      colSpan={7}
                      className="text-center text-muted-foreground py-12"
                    >
                      {allServers.length === 0
                        ? t('metrics.empty')
                        : t('metrics.noMatchingFilters')}
                    </td>
                  </tr>
                ) : (
                  filteredServers.map((server) => (
                    <tr
                      key={server.id}
                      className="border-b last:border-b-0 hover:bg-muted/30 transition-colors"
                    >
                      <td className="px-4 py-3">
                        <span className="font-medium">{server.hostname}</span>
                      </td>
                      <td className="px-4 py-3">
                        <EnvironmentBadge env={server.environment} />
                      </td>
                      <td className="px-4 py-3">
                        <StatusBadge status={server.status} />
                      </td>
                      <td className="px-4 py-3">
                        <PercentBar value={server.cpuPercent} />
                      </td>
                      <td className="px-4 py-3">
                        <PercentBar value={server.memoryPercent} />
                      </td>
                      <td className="px-4 py-3">
                        <PercentBar value={server.diskPercent} />
                      </td>
                      <td className="px-4 py-3 text-right text-muted-foreground text-xs">
                        {formatRelativeTime(server.lastCheckedAt)}
                      </td>
                    </tr>
                  ))
                )}
              </tbody>
            </table>
          </div>
        </div>
      )}

      {/* Results count */}
      {!serversLoading && !error && allServers.length > 0 && (
        <div className="mt-3 text-xs text-muted-foreground">
          {t('metrics.showing', { count: filteredServers.length, total: allServers.length })}
        </div>
      )}
    </div>
  );
}
