import { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import type { RequestLog, PageResponse } from '../../types/monitoring';
import type { ServiceInfo } from '../../types/service';
import { searchLogs } from '../../services/monitoringService';
import { getServices } from '../../services/serviceService';
import Badge from '../../components/ui/Badge';
import type { BadgeVariant } from '../../components/ui/Badge';
import Button from '../../components/ui/Button';
import { SERVICE_BADGE_VARIANTS } from '../../constants/chart';

const STATUS_VARIANT: Record<string, BadgeVariant> = {
  SUCCESS: 'success',
  FAIL: 'danger',
  DENIED: 'warning',
  EXPIRED: 'warning',
  INVALID_KEY: 'danger',
  ERROR: 'danger',
  FAILED: 'default',
};

const METHOD_VARIANT: Record<string, BadgeVariant> = {
  GET: 'success',
  POST: 'info',
  PUT: 'warning',
  DELETE: 'danger',
};

const REQUEST_STATUSES = ['SUCCESS', 'FAIL', 'DENIED', 'EXPIRED', 'INVALID_KEY', 'ERROR', 'FAILED'];
const HTTP_METHODS = ['GET', 'POST', 'PUT', 'DELETE'];
const DEFAULT_PAGE_SIZE = 20;

const formatDate = (d: Date): string => {
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
};

const getToday = (): string => formatDate(new Date());
const getTodayString = getToday;

const formatDateTime = (dateStr: string): string => {
  const d = new Date(dateStr);
  const year = d.getFullYear();
  const month = String(d.getMonth() + 1).padStart(2, '0');
  const day = String(d.getDate()).padStart(2, '0');
  const hours = String(d.getHours()).padStart(2, '0');
  const minutes = String(d.getMinutes()).padStart(2, '0');
  const seconds = String(d.getSeconds()).padStart(2, '0');
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
};

const getStatusCodeVariant = (code: number): BadgeVariant => {
  if (code >= 500) return 'danger';
  if (code >= 400) return 'warning';
  if (code >= 200) return 'success';
  return 'default';
};

const getResponseTimeClass = (ms: number): string => {
  if (ms > 1000) return 'text-[var(--color-danger)]';
  if (ms > 500) return 'text-[var(--color-warning)]';
  return 'text-[var(--color-text-primary)]';
};

const RequestLogsPage = () => {
  const navigate = useNavigate();

  const [startDate, setStartDate] = useState(() => {
    const d = new Date(); d.setDate(d.getDate() - 6); return formatDate(d);
  });
  const [endDate, setEndDate] = useState(getTodayString());
  const [datePreset, setDatePreset] = useState('최근 7일');
  const [serviceId, setServiceId] = useState('');
  const [requestStatus, setRequestStatus] = useState('');
  const [requestMethod, setRequestMethod] = useState('');
  const [searchKeyword, setSearchKeyword] = useState('');

  const [services, setServices] = useState<ServiceInfo[]>([]);
  const [serviceBadgeMap, setServiceBadgeMap] = useState<Record<string, BadgeVariant>>({}); // key: serviceName
  const [result, setResult] = useState<PageResponse<RequestLog> | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [currentPage, setCurrentPage] = useState(0);

  const fetchServices = async () => {
    try {
      const res = await getServices();
      if (res.success && res.data) {
        setServices(res.data);
        const sorted = [...res.data].sort((a, b) => a.serviceName.localeCompare(b.serviceName));
        const map: Record<string, BadgeVariant> = {};
        sorted.forEach((s, idx) => {
          map[s.serviceName] = SERVICE_BADGE_VARIANTS[idx % SERVICE_BADGE_VARIANTS.length];
        });
        setServiceBadgeMap(map);
      }
    } catch {
      // 서비스 목록 로딩 실패는 무시
    }
  };

  const handleSearch = async (page: number) => {
    setLoading(true);
    setError(null);
    setCurrentPage(page);

    try {
      const params: Record<string, string | number | undefined> = {
        startDate: startDate || undefined,
        endDate: endDate || undefined,
        serviceId: serviceId ? Number(serviceId) : undefined,
        requestStatus: requestStatus || undefined,
        requestMethod: requestMethod || undefined,
        keyword: searchKeyword || undefined,
        page,
        size: DEFAULT_PAGE_SIZE,
      };
      const res = await searchLogs(params);
      if (res.success && res.data) {
        setResult(res.data);
      } else {
        setError(res.message || '로그 조회에 실패했습니다.');
      }
    } catch {
      setError('로그 조회에 실패했습니다.');
    } finally {
      setLoading(false);
    }
  };

  const handleReset = () => {
    const d = new Date(); d.setDate(d.getDate() - 6);
    setStartDate(formatDate(d));
    setEndDate(getTodayString());
    setDatePreset('최근 7일');
    setServiceId('');
    setRequestStatus('');
    setRequestMethod('');
    setSearchKeyword('');
    setCurrentPage(0);
  };

  useEffect(() => {
    fetchServices();
    handleSearch(0);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const handleResetAndSearch = () => {
    handleReset();
    setLoading(true);
    setError(null);
    setCurrentPage(0);
    const today = getTodayString();
    const d = new Date(); d.setDate(d.getDate() - 6);
    const weekAgo = formatDate(d);
    const params: Record<string, string | number | undefined> = {
      startDate: weekAgo,
      endDate: today,
      page: 0,
      size: DEFAULT_PAGE_SIZE,
    };
    searchLogs(params)
      .then((res) => {
        if (res.success && res.data) {
          setResult(res.data);
        } else {
          setError(res.message || '로그 조회에 실패했습니다.');
        }
      })
      .catch(() => {
        setError('로그 조회에 실패했습니다.');
      })
      .finally(() => {
        setLoading(false);
      });
  };

  const handleRowClick = (logId: number) => {
    navigate(`/monitoring/request-logs/${logId}`);
  };

  const handlePrev = () => {
    if (currentPage > 0) {
      handleSearch(currentPage - 1);
    }
  };

  const handleNext = () => {
    if (result && currentPage < result.totalPages - 1) {
      handleSearch(currentPage + 1);
    }
  };

  const DATE_PRESETS = [
    {
      label: '오늘',
      fn: () => {
        const t = getToday();
        setStartDate(t);
        setEndDate(t);
        setDatePreset('오늘');
      },
    },
    {
      label: '어제',
      fn: () => {
        const d = new Date();
        d.setDate(d.getDate() - 1);
        const y = formatDate(d);
        setStartDate(y);
        setEndDate(y);
        setDatePreset('어제');
      },
    },
    {
      label: '최근 7일',
      fn: () => {
        const d = new Date();
        d.setDate(d.getDate() - 6);
        setStartDate(formatDate(d));
        setEndDate(getToday());
        setDatePreset('최근 7일');
      },
    },
    {
      label: '이번 달',
      fn: () => {
        const d = new Date();
        setStartDate(`${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-01`);
        setEndDate(getToday());
        setDatePreset('이번 달');
      },
    },
    {
      label: '지난 달',
      fn: () => {
        const d = new Date();
        d.setMonth(d.getMonth() - 1);
        const s = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-01`;
        const e = new Date(d.getFullYear(), d.getMonth() + 1, 0);
        setStartDate(s);
        setEndDate(formatDate(e));
        setDatePreset('지난 달');
      },
    },
  ];

  const activeFilters: { label: string; onRemove: () => void }[] = [];
  if (serviceId) {
    const svc = services.find((s) => String(s.serviceId) === serviceId);
    activeFilters.push({ label: `서비스: ${svc?.serviceName ?? serviceId}`, onRemove: () => setServiceId('') });
  }
  if (requestStatus) {
    activeFilters.push({ label: `상태: ${requestStatus}`, onRemove: () => setRequestStatus('') });
  }
  if (requestMethod) {
    activeFilters.push({ label: `Method: ${requestMethod}`, onRemove: () => setRequestMethod('') });
  }
  if (searchKeyword) {
    activeFilters.push({ label: `검색: ${searchKeyword}`, onRemove: () => setSearchKeyword('') });
  }

  const totalElements = result?.totalElements ?? 0;
  const totalPages = result?.totalPages ?? 1;
  const start = totalElements === 0 ? 0 : currentPage * DEFAULT_PAGE_SIZE + 1;
  const end = Math.min((currentPage + 1) * DEFAULT_PAGE_SIZE, totalElements);

  const selectClassName =
    'bg-[var(--color-bg-base)] border border-[var(--color-border)] rounded-md px-2.5 py-1.5 text-xs text-[var(--color-text-primary)] focus:outline-none';

  return (
    <div className="max-w-7xl mx-auto">
      {/* 1행: 제목 */}
      <div className="flex items-center justify-between mb-4">
        <div className="flex items-center gap-3 mb-1">
          <div className="w-10 h-10 rounded-xl bg-[var(--color-primary-subtle)] flex items-center justify-center">
            <svg className="w-5 h-5 text-[var(--color-primary)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}>
              <path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z" />
              <polyline points="14,2 14,8 20,8" />
              <line x1="16" y1="13" x2="8" y2="13" />
              <line x1="16" y1="17" x2="8" y2="17" />
            </svg>
          </div>
          <div>
            <h1 className="text-xl font-bold text-[var(--color-text-primary)]">요청 로그</h1>
            <p className="text-sm text-[var(--color-text-secondary)]">모든 API 요청/응답 로그를 조회합니다</p>
          </div>
        </div>
      </div>

      {/* 2행: 필터 카드 */}
      <div className="bg-[var(--color-bg-surface)] border border-[var(--color-border)] rounded-xl p-4 mb-4 space-y-3">
        {/* 1줄: 기간 프리셋 + 날짜 입력 */}
        <div className="flex items-center gap-2 flex-wrap">
          {/* 세그먼트 컨트롤 */}
          <div className="flex items-center rounded-md border border-[var(--color-border)] overflow-hidden">
            {DATE_PRESETS.map((preset) => (
              <button
                key={preset.label}
                type="button"
                onClick={preset.fn}
                className={`px-3 py-1.5 text-xs font-medium transition-colors ${
                  datePreset === preset.label
                    ? 'bg-[var(--color-primary)] text-white'
                    : 'text-[var(--color-text-tertiary)] hover:text-[var(--color-text-secondary)] hover:bg-[var(--color-bg-base)]'
                }`}
              >
                {preset.label}
              </button>
            ))}
          </div>

          {/* 구분선 */}
          <div className="w-px h-6 bg-[var(--color-border)]" />

          {/* 날짜 입력 */}
          <div className="flex items-center gap-1.5">
            <svg
              className="w-3.5 h-3.5 text-[var(--color-text-tertiary)]"
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"
              />
            </svg>
            <input
              type="date"
              value={startDate}
              onChange={(e) => {
                setStartDate(e.target.value);
                setDatePreset('');
              }}
              className={selectClassName}
            />
            <span className="text-xs text-[var(--color-text-tertiary)]">~</span>
            <input
              type="date"
              value={endDate}
              onChange={(e) => {
                setEndDate(e.target.value);
                setDatePreset('');
              }}
              className={selectClassName}
            />
          </div>
        </div>

        {/* 2줄: 필터 셀렉트 + URL 검색 + 버튼 */}
        <div className="flex items-center gap-2 flex-wrap">
          {/* 필터 아이콘 */}
          <svg
            className="w-3.5 h-3.5 text-[var(--color-text-tertiary)] flex-shrink-0"
            fill="none"
            stroke="currentColor"
            viewBox="0 0 24 24"
          >
            <path
              strokeLinecap="round"
              strokeLinejoin="round"
              strokeWidth={2}
              d="M3 4a1 1 0 011-1h16a1 1 0 011 1v2a1 1 0 01-.293.707L13 13.414V19a1 1 0 01-.553.894l-4 2A1 1 0 017 21v-7.586L3.293 6.707A1 1 0 013 6V4z"
            />
          </svg>

          {/* 서비스 */}
          <select value={serviceId} onChange={(e) => setServiceId(e.target.value)} className={selectClassName}>
            <option value="">서비스 전체</option>
            {services.map((s) => (
              <option key={s.serviceId} value={s.serviceId}>
                {s.serviceName}
              </option>
            ))}
          </select>

          {/* 상태 */}
          <select value={requestStatus} onChange={(e) => setRequestStatus(e.target.value)} className={selectClassName}>
            <option value="">상태 전체</option>
            {REQUEST_STATUSES.map((s) => (
              <option key={s} value={s}>
                {s}
              </option>
            ))}
          </select>

          {/* Method */}
          <select value={requestMethod} onChange={(e) => setRequestMethod(e.target.value)} className={selectClassName}>
            <option value="">Method 전체</option>
            {HTTP_METHODS.map((m) => (
              <option key={m} value={m}>
                {m}
              </option>
            ))}
          </select>

          {/* URL 검색 */}
          <div className="flex-1 min-w-[200px] relative">
            <svg
              className="absolute left-2.5 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-[var(--color-text-tertiary)]"
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
              />
            </svg>
            <input
              type="text"
              value={searchKeyword}
              onChange={(e) => setSearchKeyword(e.target.value)}
              onKeyDown={(e) => e.key === 'Enter' && handleSearch(0)}
              placeholder="URL 또는 IP로 검색..."
              className="w-full pl-8 pr-3 py-1.5 bg-[var(--color-bg-base)] border border-[var(--color-border)] rounded-md text-xs text-[var(--color-text-primary)] placeholder:text-[var(--color-text-tertiary)] focus:outline-none"
            />
          </div>

          {/* 버튼 */}
          <Button onClick={() => handleSearch(0)} variant="primary" size="sm">
            검색
          </Button>
          <Button onClick={handleResetAndSearch} variant="outline" size="sm">
            초기화
          </Button>
        </div>

        {/* 3줄: 활성 필터 칩 */}
        {activeFilters.length > 0 && (
          <div className="flex items-center gap-2 flex-wrap pt-2 border-t border-[var(--color-border)]">
            <span className="text-xs text-[var(--color-text-tertiary)]">적용된 필터:</span>
            {activeFilters.map((f) => (
              <span
                key={f.label}
                className="inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs bg-[var(--color-primary-subtle)] text-[var(--color-primary)]"
              >
                {f.label}
                <button
                  type="button"
                  onClick={f.onRemove}
                  className="hover:opacity-70 transition-opacity"
                  aria-label="필터 해제"
                >
                  <svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
                  </svg>
                </button>
              </span>
            ))}
          </div>
        )}
      </div>

      {/* 에러 메시지 */}
      {error && (
        <div className="mb-4 p-3 rounded-lg text-sm bg-[var(--color-danger)]/10 text-[var(--color-danger)]">
          {error}
        </div>
      )}

      {/* 3행: 로그 테이블 */}
      <div className="bg-[var(--color-bg-surface)] border border-[var(--color-border)] rounded-xl overflow-hidden mb-4">
        {loading ? (
          <div className="text-center py-10 text-[var(--color-text-secondary)] text-sm">로딩 중...</div>
        ) : (
          <div className="overflow-x-auto">
            <table className="w-full divide-y divide-[var(--color-border)] text-sm">
              <thead className="bg-[var(--color-bg-base)]">
                <tr>
                  <th className="px-3 py-2 text-left text-xs font-medium text-[var(--color-text-secondary)] uppercase tracking-wider">
                    시간
                  </th>
                  <th className="px-3 py-2 text-left text-xs font-medium text-[var(--color-text-secondary)] uppercase tracking-wider">
                    서비스
                  </th>
                  <th className="px-3 py-2 text-left text-xs font-medium text-[var(--color-text-secondary)] uppercase tracking-wider">
                    Method
                  </th>
                  <th className="px-3 py-2 text-left text-xs font-medium text-[var(--color-text-secondary)] uppercase tracking-wider">
                    URL
                  </th>
                  <th className="px-3 py-2 text-left text-xs font-medium text-[var(--color-text-secondary)] uppercase tracking-wider">
                    응답코드
                  </th>
                  <th className="px-3 py-2 text-left text-xs font-medium text-[var(--color-text-secondary)] uppercase tracking-wider">
                    응답시간
                  </th>
                  <th className="px-3 py-2 text-left text-xs font-medium text-[var(--color-text-secondary)] uppercase tracking-wider">
                    응답결과
                  </th>
                  <th className="px-3 py-2 text-left text-xs font-medium text-[var(--color-text-secondary)] uppercase tracking-wider">
                    IP
                  </th>
                </tr>
              </thead>
              <tbody className="divide-y divide-[var(--color-border)]">
                {result && result.content.length > 0 ? (
                  result.content.map((log) => (
                    <tr
                      key={log.logId}
                      onClick={() => handleRowClick(log.logId)}
                      className="cursor-pointer hover:bg-[var(--color-bg-base)] transition-colors"
                    >
                      {/* 시간 */}
                      <td className="px-3 py-1 whitespace-nowrap text-xs text-[var(--color-text-secondary)]">
                        {formatDateTime(log.requestedAt)}
                      </td>

                      {/* 서비스 — filled Badge (rounded-md, 고정 너비) */}
                      <td className="px-3 py-1 whitespace-nowrap">
                        {log.serviceName ? (
                          <Badge variant={serviceBadgeMap[log.serviceName] ?? 'blue'} size="sm" className="rounded-md w-16 justify-center">
                            {log.serviceName}
                          </Badge>
                        ) : (
                          <span className="text-xs text-[var(--color-text-tertiary)]">-</span>
                        )}
                      </td>

                      {/* Method — pill Badge */}
                      <td className="px-3 py-1 whitespace-nowrap">
                        <Badge variant={METHOD_VARIANT[log.requestMethod] ?? 'default'} size="sm">
                          {log.requestMethod}
                        </Badge>
                      </td>

                      {/* URL */}
                      <td
                        className="px-3 py-1 text-xs text-[var(--color-text-secondary)] truncate max-w-[340px]"
                        title={log.requestUrl}
                      >
                        {log.requestUrl}
                      </td>

                      {/* 응답코드 — pill Badge */}
                      <td className="px-3 py-1 whitespace-nowrap">
                        {log.responseStatus != null ? (
                          <Badge variant={getStatusCodeVariant(log.responseStatus)} size="sm">
                            {log.responseStatus}
                          </Badge>
                        ) : (
                          <span className="text-xs text-[var(--color-text-tertiary)]">-</span>
                        )}
                      </td>

                      {/* 응답시간 */}
                      <td className="px-3 py-1 whitespace-nowrap">
                        {log.responseTime != null ? (
                          <span className={`text-xs ${getResponseTimeClass(log.responseTime)}`}>
                            {log.responseTime}
                            <span className="text-[var(--color-text-tertiary)] ml-0.5">ms</span>
                          </span>
                        ) : (
                          <span className="text-xs text-[var(--color-text-tertiary)]">-</span>
                        )}
                      </td>

                      {/* 응답결과 — pill Badge */}
                      <td className="px-3 py-1 whitespace-nowrap">
                        <Badge variant={STATUS_VARIANT[log.requestStatus] ?? 'default'} size="sm">
                          {log.requestStatus}
                        </Badge>
                      </td>

                      {/* IP */}
                      <td className="px-3 py-1 whitespace-nowrap text-xs text-[var(--color-text-tertiary)]">
                        {log.requestIp}
                      </td>
                    </tr>
                  ))
                ) : (
                  <tr>
                    <td colSpan={8} className="px-3 py-10 text-center text-sm text-[var(--color-text-tertiary)]">
                      검색 결과가 없습니다
                    </td>
                  </tr>
                )}
              </tbody>
            </table>
          </div>
        )}

        {/* 4행: 페이지네이션 (테이블 카드 내부 하단) */}
        {result && result.totalElements > 0 && (
          <div className="flex items-center justify-between px-4 py-3 border-t border-[var(--color-border)]">
            <span className="text-xs text-[var(--color-text-tertiary)]">
              총{' '}
              <span className="text-[var(--color-text-primary)] font-semibold">{totalElements}</span>건 중{' '}
              <span className="text-[var(--color-text-primary)] font-semibold">
                {start}-{end}
              </span>
              건 표시
            </span>
            <div className="flex items-center gap-2">
              <button
                type="button"
                onClick={handlePrev}
                disabled={currentPage === 0}
                className="px-3 py-1.5 rounded-md border border-[var(--color-border)] text-xs text-[var(--color-text-secondary)] hover:bg-[var(--color-bg-base)] disabled:opacity-40 transition-colors"
              >
                ← 이전
              </button>
              <span className="text-xs">
                <span className="text-[var(--color-text-primary)] font-bold">{currentPage + 1}</span>
                <span className="text-[var(--color-text-tertiary)]"> / </span>
                <span className="text-[var(--color-text-secondary)]">{totalPages}</span>
              </span>
              <button
                type="button"
                onClick={handleNext}
                disabled={!result || currentPage >= result.totalPages - 1}
                className="px-3 py-1.5 rounded-md border border-[var(--color-border)] text-xs text-[var(--color-text-secondary)] hover:bg-[var(--color-bg-base)] disabled:opacity-40 transition-colors"
              >
                다음 →
              </button>
            </div>
          </div>
        )}
      </div>
    </div>
  );
};

export default RequestLogsPage;
