import { useState, useEffect, useCallback, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import {
  LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer,
  PieChart, Pie, Cell, AreaChart, Area,
} from 'recharts';
import type { DashboardStats, HourlyTrend, ServiceRatio, ErrorTrend, TopApi } from '../types/dashboard';
import type { RequestLog } from '../types/monitoring';
import type { HeartbeatStatus } from '../types/service';
import {
  getSummary, getHourlyTrend, getServiceRatio,
  getErrorTrend, getTopApis, getRecentLogs, getHeartbeat,
} from '../services/dashboardService';
import { CHART_COLORS_HEX } from '../constants/chart';
import { useTheme } from '../hooks/useTheme';

const SERVICE_TAG_STYLES = [
  'bg-blue-100 text-blue-700',
  'bg-emerald-100 text-emerald-700',
  'bg-amber-100 text-amber-700',
  'bg-red-100 text-red-700',
  'bg-violet-100 text-violet-700',
  'bg-cyan-100 text-cyan-700',
];

const STATUS_BADGE: Record<string, string> = {
  SUCCESS: 'bg-green-100 text-green-800',
  FAIL: 'bg-red-100 text-red-800',
  DENIED: 'bg-red-100 text-red-800',
  EXPIRED: 'bg-orange-100 text-orange-800',
  INVALID_KEY: 'bg-red-100 text-red-800',
  ERROR: 'bg-orange-100 text-orange-800',
  FAILED: 'bg-gray-100 text-gray-800',
};

const AUTO_REFRESH_MS = 30000;

const extractSettled = <T,>(result: PromiseSettledResult<{ data?: T }>, fallback: T): T => {
  if (result.status === 'fulfilled' && result.value.data !== undefined) {
    return result.value.data;
  }
  return fallback;
};

const truncate = (str: string, max: number): string => {
  return str.length > max ? str.slice(0, max) + '...' : str;
};

const DashboardPage = () => {
  const navigate = useNavigate();
  const { theme } = useTheme();
  const chartColors = CHART_COLORS_HEX[theme];

  const [stats, setStats] = useState<DashboardStats | null>(null);
  const [heartbeat, setHeartbeat] = useState<HeartbeatStatus[]>([]);
  const [hourlyTrend, setHourlyTrend] = useState<HourlyTrend[]>([]);
  const [serviceRatio, setServiceRatio] = useState<ServiceRatio[]>([]);
  const [errorTrend, setErrorTrend] = useState<ErrorTrend[]>([]);
  const [topApis, setTopApis] = useState<TopApi[]>([]);
  const [recentLogs, setRecentLogs] = useState<RequestLog[]>([]);
  const [lastUpdated, setLastUpdated] = useState<string>('');
  const [isLoading, setIsLoading] = useState(true);

  const fetchAll = useCallback(async () => {
    try {
      const [summaryRes, heartbeatRes, hourlyRes, serviceRes, errorRes, topRes, logsRes] =
        await Promise.allSettled([
          getSummary(),
          getHeartbeat(),
          getHourlyTrend(),
          getServiceRatio(),
          getErrorTrend(),
          getTopApis(),
          getRecentLogs(),
        ]);

      setStats(extractSettled<DashboardStats | null>(summaryRes, null));
      setHeartbeat(extractSettled<HeartbeatStatus[]>(heartbeatRes, []));
      setHourlyTrend(extractSettled<HourlyTrend[]>(hourlyRes, []));
      setServiceRatio(extractSettled<ServiceRatio[]>(serviceRes, []));
      setErrorTrend(extractSettled<ErrorTrend[]>(errorRes, []));
      setTopApis(extractSettled<TopApi[]>(topRes, []));
      setRecentLogs(extractSettled<RequestLog[]>(logsRes, []));
      setLastUpdated(new Date().toLocaleTimeString('ko-KR'));
    } finally {
      setIsLoading(false);
    }
  }, []);

  useEffect(() => {
    fetchAll();
    const interval = setInterval(fetchAll, AUTO_REFRESH_MS);
    return () => clearInterval(interval);
  }, [fetchAll]);

  const errorTrendPivoted = useMemo(() => {
    const serviceNames = [...new Set(errorTrend.map((e) => e.serviceName))];
    const byHour: Record<number, Record<string, number>> = {};
    for (const item of errorTrend) {
      if (!byHour[item.hour]) {
        byHour[item.hour] = { hour: item.hour };
      }
      byHour[item.hour][item.serviceName] = item.errorRate;
    }
    return {
      data: Object.values(byHour),
      serviceNames,
    };
  }, [errorTrend]);

  const topApiServiceColorMap = useMemo(() => {
    const serviceNames = [...new Set(topApis.map((a) => a.serviceName))];
    const map: Record<string, { tag: string; bar: string }> = {};
    serviceNames.forEach((name, i) => {
      map[name] = {
        tag: SERVICE_TAG_STYLES[i % SERVICE_TAG_STYLES.length],
        bar: chartColors[i % chartColors.length],
      };
    });
    return map;
  }, [topApis, chartColors]);

  if (isLoading) {
    return (
      <div className="flex items-center justify-center h-64">
        <div className="text-[var(--color-text-secondary)]">Loading...</div>
      </div>
    );
  }

  return (
    <div>
      {/* Header */}
      <div className="flex items-center justify-between mb-6">
        <h1 className="text-2xl font-bold text-[var(--color-text-primary)]">Dashboard</h1>
        {lastUpdated && (
          <span className="text-sm text-[var(--color-text-secondary)]">마지막 갱신: {lastUpdated}</span>
        )}
      </div>

      {/* Row 1: Summary Cards */}
      {stats && (
        <div className="grid grid-cols-4 gap-4 mb-6">
          <div className="bg-[var(--color-bg-surface)] rounded-lg shadow p-6">
            <p className="text-sm text-[var(--color-text-secondary)]">오늘 총 요청</p>
            <p className="text-3xl font-bold text-[var(--color-text-primary)]">{stats.totalRequests.toLocaleString()}</p>
            <p className={`text-sm ${stats.changePercent > 0 ? 'text-green-600' : stats.changePercent < 0 ? 'text-red-600' : 'text-[var(--color-text-secondary)]'}`}>
              {stats.changePercent > 0 ? '\u25B2' : stats.changePercent < 0 ? '\u25BC' : ''} 전일 대비 {stats.changePercent.toFixed(2)}%
            </p>
          </div>
          <div className="bg-[var(--color-bg-surface)] rounded-lg shadow p-6">
            <p className="text-sm text-[var(--color-text-secondary)]">성공률</p>
            <p className="text-3xl font-bold text-[var(--color-text-primary)]">{stats.successRate.toFixed(1)}%</p>
            <p className="text-sm text-red-500">실패 {stats.failureCount}건</p>
          </div>
          <div className="bg-[var(--color-bg-surface)] rounded-lg shadow p-6">
            <p className="text-sm text-[var(--color-text-secondary)]">평균 응답 시간</p>
            <p className="text-3xl font-bold text-[var(--color-text-primary)]">{stats.avgResponseTime.toFixed(0)}ms</p>
          </div>
          <div className="bg-[var(--color-bg-surface)] rounded-lg shadow p-6">
            <p className="text-sm text-[var(--color-text-secondary)]">API 요청 사용자</p>
            <p className="text-3xl font-bold text-[var(--color-text-primary)]">{stats.activeUserCount}</p>
            <p className="text-sm text-[var(--color-text-secondary)]">오늘</p>
          </div>
        </div>
      )}

      {/* Row 2: Heartbeat Status Cards */}
      <div className="mb-6">
        {heartbeat.length > 0 ? (
          <div className="flex gap-4">
            {heartbeat.map((svc) => {
              const isUp = svc.healthStatus === 'UP';
              const isDown = svc.healthStatus === 'DOWN';
              const borderColor = isUp ? 'border-green-500' : isDown ? 'border-red-500' : 'border-gray-400';

              return (
                <div
                  key={svc.serviceId}
                  className={`flex-1 bg-[var(--color-bg-surface)] rounded-lg shadow p-4 border-l-4 ${borderColor} cursor-pointer hover:shadow-md transition-shadow`}
                  onClick={() => navigate('/monitoring/service-status')}
                >
                  <div className="flex items-center gap-2 mb-2">
                    <div
                      className={`w-3 h-3 rounded-full ${
                        isUp ? 'bg-green-500' : isDown ? 'bg-red-500' : 'bg-gray-400'
                      }`}
                    />
                    <span className="font-medium text-[var(--color-text-primary)]">{svc.serviceName}</span>
                  </div>
                  <div className="flex items-center justify-between text-sm">
                    <span className={`font-medium ${isUp ? 'text-green-600' : isDown ? 'text-red-600' : 'text-[var(--color-text-secondary)]'}`}>
                      {isUp ? 'Operational' : isDown ? 'Down' : 'Unknown'}
                    </span>
                    {svc.healthCheckedAt && (
                      <span className="text-[var(--color-text-tertiary)] text-xs">{svc.healthCheckedAt}</span>
                    )}
                  </div>
                </div>
              );
            })}
          </div>
        ) : (
          <div className="bg-[var(--color-bg-surface)] rounded-lg shadow p-4">
            <p className="text-[var(--color-text-secondary)] text-sm">등록된 서비스가 없습니다</p>
          </div>
        )}
      </div>

      {/* Row 3: Charts 2x2 */}
      <div className="grid grid-cols-2 gap-6 mb-6">
        {/* Chart 1: Hourly Trend */}
        <div className="bg-[var(--color-bg-surface)] rounded-lg shadow p-6">
          <h3 className="text-lg font-semibold text-[var(--color-text-primary)] mb-4">시간별 요청 추이</h3>
          {hourlyTrend.length > 0 ? (
            <ResponsiveContainer width="100%" height={300}>
              <LineChart data={hourlyTrend}>
                <CartesianGrid strokeDasharray="3 3" />
                <XAxis dataKey="hour" tickFormatter={(h: number) => `${h}시`} />
                <YAxis />
                <Tooltip labelFormatter={(h) => `${h}시`} />
                <Legend />
                <Line type="monotone" dataKey="successCount" stroke={chartColors[0]} name="성공" />
                <Line type="monotone" dataKey="failureCount" stroke="#ef4444" name="실패" />
              </LineChart>
            </ResponsiveContainer>
          ) : (
            <p className="text-[var(--color-text-tertiary)] text-center py-20">데이터가 없습니다</p>
          )}
        </div>

        {/* Chart 2: Service Ratio */}
        <div className="bg-[var(--color-bg-surface)] rounded-lg shadow p-6">
          <h3 className="text-lg font-semibold text-[var(--color-text-primary)] mb-4">서비스별 요청 비율</h3>
          {serviceRatio.length > 0 ? (
            <ResponsiveContainer width="100%" height={300}>
              <PieChart>
                <Pie
                  data={serviceRatio}
                  dataKey="count"
                  nameKey="serviceName"
                  innerRadius={60}
                  outerRadius={100}
                >
                  {serviceRatio.map((_, idx) => (
                    <Cell key={idx} fill={chartColors[idx % chartColors.length]} />
                  ))}
                </Pie>
                <Tooltip />
                <Legend layout="vertical" align="right" verticalAlign="middle" />
              </PieChart>
            </ResponsiveContainer>
          ) : (
            <p className="text-[var(--color-text-tertiary)] text-center py-20">데이터가 없습니다</p>
          )}
        </div>

        {/* Chart 3: Error Trend */}
        <div className="bg-[var(--color-bg-surface)] rounded-lg shadow p-6">
          <h3 className="text-lg font-semibold text-[var(--color-text-primary)] mb-4">에러율 추이</h3>
          {errorTrendPivoted.data.length > 0 ? (
            <ResponsiveContainer width="100%" height={300}>
              <AreaChart data={errorTrendPivoted.data}>
                <CartesianGrid strokeDasharray="3 3" />
                <XAxis dataKey="hour" tickFormatter={(h: number) => `${h}시`} />
                <YAxis unit="%" />
                <Tooltip labelFormatter={(h) => `${h}시`} />
                <Legend />
                {errorTrendPivoted.serviceNames.map((name, idx) => (
                  <Area
                    key={name}
                    type="monotone"
                    dataKey={name}
                    stackId="1"
                    stroke={chartColors[idx % chartColors.length]}
                    fill={chartColors[idx % chartColors.length]}
                    fillOpacity={0.3}
                  />
                ))}
              </AreaChart>
            </ResponsiveContainer>
          ) : (
            <p className="text-[var(--color-text-tertiary)] text-center py-20">데이터가 없습니다</p>
          )}
        </div>

        {/* Chart 4: Top APIs */}
        <div className="bg-[var(--color-bg-surface)] rounded-lg shadow p-6">
          <h3 className="text-lg font-semibold text-[var(--color-text-primary)] mb-4">상위 호출 API</h3>
          {topApis.length > 0 ? (
            <div className="space-y-2">
              {topApis.map((api, idx) => {
                const maxCount = topApis[0]?.count || 1;
                const pct = (api.count / maxCount) * 100;
                const colors = topApiServiceColorMap[api.serviceName] || { tag: SERVICE_TAG_STYLES[0], bar: chartColors[0] };
                return (
                  <div key={idx} className="flex items-center gap-3">
                    <span className="text-xs text-[var(--color-text-tertiary)] w-5 text-right">{idx + 1}</span>
                    <span className={`shrink-0 px-1.5 py-0.5 rounded text-xs font-medium ${colors.tag}`}>
                      {api.serviceName}
                    </span>
                    <span className="shrink-0 text-sm text-[var(--color-text-primary)] w-48 truncate" title={api.apiName}>
                      {api.apiName}
                    </span>
                    <div className="flex-1 bg-[var(--color-bg-base)] rounded-full h-5 relative">
                      <div
                        className="h-5 rounded-full"
                        style={{ width: `${pct}%`, backgroundColor: colors.bar }}
                      />
                    </div>
                    <span className="text-sm font-medium text-[var(--color-text-primary)] w-12 text-right">{api.count}</span>
                  </div>
                );
              })}
            </div>
          ) : (
            <p className="text-[var(--color-text-tertiary)] text-center py-20">데이터가 없습니다</p>
          )}
        </div>
      </div>

      {/* Row 4: Recent Logs */}
      <div className="bg-[var(--color-bg-surface)] rounded-lg shadow mb-6">
        <div className="p-6 border-b border-[var(--color-border)]">
          <h3 className="text-lg font-semibold text-[var(--color-text-primary)]">최근 요청 로그</h3>
        </div>
        {recentLogs.length > 0 ? (
          <>
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead className="bg-[var(--color-bg-base)]">
                <tr>
                  <th className="px-4 py-3 text-left text-xs font-medium text-[var(--color-text-secondary)] uppercase">시간</th>
                  <th className="px-4 py-3 text-left text-xs font-medium text-[var(--color-text-secondary)] uppercase">서비스</th>
                  <th className="px-4 py-3 text-left text-xs font-medium text-[var(--color-text-secondary)] uppercase">사용자</th>
                  <th className="px-4 py-3 text-left text-xs font-medium text-[var(--color-text-secondary)] uppercase">URL</th>
                  <th className="px-4 py-3 text-left text-xs font-medium text-[var(--color-text-secondary)] uppercase">상태</th>
                  <th className="px-4 py-3 text-left text-xs font-medium text-[var(--color-text-secondary)] uppercase">응답시간</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-[var(--color-border)]">
                {recentLogs.slice(0, 5).map((log) => (
                  <tr
                    key={log.logId}
                    className="hover:bg-[var(--color-bg-base)] cursor-pointer"
                    onClick={() => navigate(`/monitoring/request-logs/${log.logId}`)}
                  >
                    <td className="px-4 py-3 text-[var(--color-text-tertiary)] whitespace-nowrap">{log.requestedAt}</td>
                    <td className="px-4 py-3 text-[var(--color-text-primary)]">{log.serviceName ?? '-'}</td>
                    <td className="px-4 py-3 text-[var(--color-text-primary)]">{log.userName ?? '-'}</td>
                    <td className="px-4 py-3 text-[var(--color-text-primary)]" title={log.requestUrl}>
                      {truncate(log.requestUrl, 40)}
                    </td>
                    <td className="px-4 py-3">
                      <span className={`px-2 py-1 rounded-full text-xs font-medium ${STATUS_BADGE[log.requestStatus] ?? 'bg-gray-100 text-gray-800'}`}>
                        {log.requestStatus}
                      </span>
                    </td>
                    <td className="px-4 py-3 text-[var(--color-text-tertiary)]">
                      {log.responseTime !== null ? `${log.responseTime}ms` : '-'}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
          <div className="px-6 py-3 border-t border-[var(--color-border)] text-center">
            <button
              onClick={() => navigate('/monitoring/request-logs')}
              className="text-sm text-[var(--color-primary)] hover:text-[var(--color-primary-hover)] font-medium"
            >
              더보기 →
            </button>
          </div>
          </>
        ) : (
          <p className="text-[var(--color-text-tertiary)] text-center py-8">요청 로그가 없습니다</p>
        )}
      </div>
    </div>
  );
};

export default DashboardPage;
