'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 HealthCheckResult {
  id: string;
  serverId: string;
  serverName: string;
  serverHost: string;
  checkType: 'ping' | 'tcp' | 'http';
  status: 'healthy' | 'degraded' | 'down';
  latencyMs: number;
  uptimePercent: number;
  lastCheckedAt: string;
  message?: string;
}

type HealthChecksResponse = HealthCheckResult[];

type StatusFilter = 'all' | 'healthy' | 'degraded' | 'down';
type RefreshInterval = 0 | 10 | 30 | 60;

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

const STATUS_FILTERS: { labelKey: string; value: StatusFilter }[] = [
  { labelKey: 'healthChecks.filters.all', value: 'all' },
  { labelKey: 'healthChecks.filters.healthy', value: 'healthy' },
  { labelKey: 'healthChecks.filters.degraded', value: 'degraded' },
  { labelKey: 'healthChecks.filters.down', value: 'down' },
];

const REFRESH_OPTIONS: { labelKey: string; value: RefreshInterval }[] = [
  { labelKey: 'healthChecks.refreshOptions.off', value: 0 },
  { labelKey: 'healthChecks.refreshOptions.10s', value: 10 },
  { labelKey: 'healthChecks.refreshOptions.30s', value: 30 },
  { labelKey: 'healthChecks.refreshOptions.60s', value: 60 },
];

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

function formatRelativeTime(dateString: string): string {
  try {
    const now = Date.now();
    const then = new Date(dateString).getTime();
    const diffMs = now - then;
    if (diffMs < 0) return 'just now';
    const seconds = Math.floor(diffMs / 1000);
    if (seconds < 60) return `${seconds}s ago`;
    const minutes = Math.floor(seconds / 60);
    if (minutes < 60) return `${minutes} min 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 dateString;
  }
}

function getStatusDotColor(status: HealthCheckResult['status']): string {
  const colors: Record<HealthCheckResult['status'], string> = {
    healthy: 'bg-green-500',
    degraded: 'bg-yellow-500',
    down: 'bg-red-500',
  };
  return colors[status];
}

function getLatencyColor(ms: number): string {
  if (ms < 100) return 'text-green-600 dark:text-green-400';
  if (ms < 500) return 'text-yellow-600 dark:text-yellow-400';
  return 'text-red-600 dark:text-red-400';
}

function getUptimeColor(percent: number): string {
  if (percent >= 99.9) return 'text-green-600 dark:text-green-400';
  if (percent >= 95) return 'text-yellow-600 dark:text-yellow-400';
  return 'text-red-600 dark:text-red-400';
}

function getCheckTypeBadgeColor(type: HealthCheckResult['checkType']): string {
  const colors: Record<HealthCheckResult['checkType'], string> = {
    ping: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',
    tcp: 'bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400',
    http: 'bg-indigo-100 text-indigo-700 dark:bg-indigo-900/30 dark:text-indigo-400',
  };
  return colors[type];
}

// ---------------------------------------------------------------------------
// Summary stat card
// ---------------------------------------------------------------------------

function StatCard({ label, value, dotColor }: { label: string; value: number; dotColor?: string }) {
  return (
    <div className="bg-card border rounded-lg p-4">
      <div className="flex items-center gap-2 mb-1">
        {dotColor && <span className={cn('w-2.5 h-2.5 rounded-full', dotColor)} />}
        <span className="text-sm text-muted-foreground">{label}</span>
      </div>
      <p className="text-2xl font-bold">{value}</p>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Health check card
// ---------------------------------------------------------------------------

function HealthCheckCard({ check }: { check: HealthCheckResult }) {
  const { t } = useTranslation('monitoring');
  return (
    <div className="bg-card border rounded-lg p-4 hover:shadow-sm transition-shadow">
      <div className="flex items-start justify-between gap-3 mb-3">
        <div className="min-w-0">
          <div className="flex items-center gap-2">
            <span className={cn('w-2.5 h-2.5 rounded-full flex-shrink-0', getStatusDotColor(check.status))} />
            <h3 className="text-sm font-semibold truncate">{check.serverName}</h3>
          </div>
          <p className="text-xs text-muted-foreground font-mono mt-0.5 ml-[18px]">{check.serverHost}</p>
        </div>
        <span className={cn('inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium uppercase flex-shrink-0', getCheckTypeBadgeColor(check.checkType))}>
          {t(`healthChecks.checkTypes.${check.checkType}`)}
        </span>
      </div>

      <div className="grid grid-cols-3 gap-3 text-center">
        <div>
          <p className="text-xs text-muted-foreground mb-0.5">{t('healthChecks.card.latency')}</p>
          <p className={cn('text-sm font-semibold', getLatencyColor(check.latencyMs))}>{check.latencyMs}ms</p>
        </div>
        <div>
          <p className="text-xs text-muted-foreground mb-0.5">{t('healthChecks.card.uptime24h')}</p>
          <p className={cn('text-sm font-semibold', getUptimeColor(check.uptimePercent))}>{check.uptimePercent.toFixed(1)}%</p>
        </div>
        <div>
          <p className="text-xs text-muted-foreground mb-0.5">{t('healthChecks.card.lastCheck')}</p>
          <p className="text-sm font-medium text-muted-foreground">{formatRelativeTime(check.lastCheckedAt)}</p>
        </div>
      </div>

      {check.message && (
        <p className="mt-3 text-xs text-muted-foreground border-t pt-2 truncate" title={check.message}>
          {check.message}
        </p>
      )}
    </div>
  );
}

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

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

  const [statusFilter, setStatusFilter] = useState<StatusFilter>('all');
  const [refreshInterval, setRefreshInterval] = useState<RefreshInterval>(0);

  const { data, isLoading, error } = useQuery({
    queryKey: queryKeys.healthChecks.list(),
    queryFn: () => apiClient<HealthChecksResponse>('/api/v1/monitor/health-checks'),
  });

  const allChecks = Array.isArray(data) ? data : [];

  const filteredChecks = useMemo(() => {
    if (statusFilter === 'all') return allChecks;
    return allChecks.filter((c) => c.status === statusFilter);
  }, [allChecks, statusFilter]);

  const stats = useMemo(() => {
    const total = allChecks.length;
    const healthy = allChecks.filter((c) => c.status === 'healthy').length;
    const degraded = allChecks.filter((c) => c.status === 'degraded').length;
    const down = allChecks.filter((c) => c.status === 'down').length;
    return { total, healthy, degraded, down };
  }, [allChecks]);

  useEffect(() => {
    if (refreshInterval === 0) return;
    const intervalId = setInterval(() => {
      queryClient.invalidateQueries({ queryKey: queryKeys.healthChecks.all });
    }, refreshInterval * 1000);
    return () => clearInterval(intervalId);
  }, [refreshInterval, queryClient]);

  const handleRefreshChange = useCallback((value: RefreshInterval) => {
    setRefreshInterval(value);
  }, []);

  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('healthChecks.title')}</h1>
          <p className="text-sm text-muted-foreground mt-1">{t('healthChecks.subtitle')}</p>
        </div>
        <div className="flex items-center gap-2">
          <span className="text-sm text-muted-foreground">{t('healthChecks.autoRefresh')}</span>
          <select
            value={refreshInterval}
            onChange={(e) => handleRefreshChange(Number(e.target.value) as RefreshInterval)}
            className="px-2 py-1.5 bg-background border border-input rounded-md text-sm"
          >
            {REFRESH_OPTIONS.map((opt) => (
              <option key={opt.value} value={opt.value}>{t(opt.labelKey)}</option>
            ))}
          </select>
          {refreshInterval > 0 && (
            <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('healthChecks.live')}
            </span>
          )}
        </div>
      </div>

      {/* Summary stats */}
      <div className="grid grid-cols-2 sm:grid-cols-4 gap-4 mb-6">
        <StatCard label={t('healthChecks.stats.totalServers')} value={stats.total} />
        <StatCard label={t('healthChecks.stats.healthy')} value={stats.healthy} dotColor="bg-green-500" />
        <StatCard label={t('healthChecks.stats.degraded')} value={stats.degraded} dotColor="bg-yellow-500" />
        <StatCard label={t('healthChecks.stats.down')} value={stats.down} dotColor="bg-red-500" />
      </div>

      {/* Filter tabs */}
      <div className="flex gap-1 mb-6 p-1 bg-muted rounded-lg w-fit">
        {STATUS_FILTERS.map((filter) => (
          <button
            key={filter.value}
            onClick={() => setStatusFilter(filter.value)}
            className={cn(
              'px-4 py-1.5 text-sm rounded-md font-medium transition-colors',
              statusFilter === filter.value
                ? 'bg-background text-foreground shadow-sm'
                : 'text-muted-foreground hover:text-foreground',
            )}
          >
            {t(filter.labelKey)}
            {filter.value !== 'all' && (
              <span className="ml-1.5 text-xs text-muted-foreground">
                {filter.value === 'healthy' && stats.healthy}
                {filter.value === 'degraded' && stats.degraded}
                {filter.value === 'down' && stats.down}
              </span>
            )}
          </button>
        ))}
      </div>

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

      {isLoading && (
        <div className="text-sm text-muted-foreground py-12 text-center">{t('healthChecks.loading')}</div>
      )}

      {!isLoading && !error && (
        <>
          {filteredChecks.length === 0 ? (
            <div className="text-sm text-muted-foreground py-12 text-center">
              {statusFilter === 'all' ? t('healthChecks.empty') : t('healthChecks.noMatchingStatus', { status: statusFilter })}
            </div>
          ) : (
            <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
              {filteredChecks.map((check) => (
                <HealthCheckCard key={check.id} check={check} />
              ))}
            </div>
          )}
        </>
      )}
    </div>
  );
}
