import axios from 'axios';
import { getApiBaseUrl } from './apiConfig';

// API 베이스 URL (통합 설정 사용)
const API_BASE_URL = getApiBaseUrl();

const alertApi = axios.create({
  baseURL: API_BASE_URL,
  timeout: 60000, // 60초로 증가 (외부 DB 연결 시간 고려)
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  },
  withCredentials: false,
});

// ==================== Types ====================

export type IndicatorType = 
  | 'VOLUME'
  | 'MACD'
  | 'STOCHASTIC'
  | 'STOCHASTIC_K'
  | 'STOCHASTIC_D'
  | 'RSI'
  | 'ADX'
  | 'CCI'
  | 'TRIX'
  | 'DISPARITY'
  | 'NEW_PSYCHOLOGICAL'
  | 'INVEST_PSYCHOLOGICAL'
  | 'WILLIAMS_R'
  | 'BWI'
  | 'OBV'
  | 'VOLUME_OSC'
  | 'VR'
  | 'DMI';

export type ConditionType =
  | 'CROSS_UP'
  | 'CROSS_DOWN'
  | 'ABOVE'
  | 'BELOW'
  | 'EQUAL'
  | 'BETWEEN'
  | 'ZERO_CROSS_UP'
  | 'ZERO_CROSS_DOWN'
  | 'SIGNAL_CROSS_UP'
  | 'SIGNAL_CROSS_DOWN'
  | 'HISTOGRAM_POSITIVE'
  | 'HISTOGRAM_NEGATIVE'
  | 'HISTOGRAM_INCREASE'
  | 'HISTOGRAM_DECREASE'
  | 'K_CROSS_D_UP'
  | 'K_CROSS_D_DOWN'
  | 'VOLUME_SPIKE'
  | 'VOLUME_ABOVE_AVG'
  | 'VOLUME_BELOW_AVG'
  | 'INCREASE'
  | 'DECREASE'
  | 'GOLDEN_CROSS'
  | 'DEAD_CROSS';

export interface AlertConditionDto {
  id?: number;
  cryptoAlertId?: number;
  indicatorType: IndicatorType;
  conditionType: ConditionType;
  targetValue?: number;
  secondaryValue?: number;
  period?: number;
  comparePeriod?: number;
  enabled?: boolean;
  orderIndex?: number;
  description?: string;
  logicalOperator?: 'AND' | 'OR';
}

export interface CryptoAlertDto {
  id?: number;
  symbol: string;
  koreanName: string;
  englishName?: string;
  enabled?: boolean;
  userId?: number;
  conditions?: AlertConditionDto[]; // 하위 호환성
  createdAt?: string;
  updatedAt?: string;
}

export interface AlertNotificationDto {
  id?: number;
  cryptoAlertId?: number;
  symbol?: string;
  koreanName?: string;
  message: string;
  conditionDescription?: string;
  isRead?: boolean;
  triggeredAt?: string;
  notifiedAt?: string;
  userId?: number;
  /** 조건 충족한 봉 시각(백엔드 LocalDateTime → ISO 또는 배열) */
  candleTime?: string;
  /** 알림 스케줄/조건의 캔들 간격 (예: 3m, 1h, 1d) */
  timeInterval?: string;
}

export interface IndicatorDataDto {
  time?: string;
  open?: number;
  high?: number;
  low?: number;
  price?: number;
  ma10?: number;
  ma20?: number;
  ma60?: number;
  ma120?: number;
  rsi?: number;
  macdLine?: number;
  signalLine?: number;
  histogram?: number;
  stochK?: number;
  stochD?: number;
  cci?: number;
  adx?: number;
  plusDI?: number;
  minusDI?: number;
  williamsR?: number;
  newPsy?: number;
  investPsy?: number;
  bwi?: number;
  obv?: number;
  obvSignal?: number;     // OBV Signal Line (이동평균)
  volumeOsc?: number;
  vr?: number;
  trix?: number;
  trixSignal?: number;    // TRIX Signal Line
  ichimokuTenkan?: number;
  ichimokuKijun?: number;
  ichimokuSenkouA?: number;
  ichimokuSenkouB?: number;
  ichimokuChikou?: number;
  disparityMid?: number;
  volume?: number;
}

export interface AlertNotificationDetailDto extends AlertNotificationDto {
  englishName?: string;
  indicatorData?: IndicatorDataDto;
  /** 알림 발생 시점 전후 지표 시계열 (조건 관련 차트 렌더링용) */
  indicatorDataSeries?: IndicatorDataDto[];
  satisfiedConditions?: AlertConditionDto[];
  currentPrice?: number;
  changeRate?: number;
  volume?: number;
  /** 백엔드: 알림 발생 봉 기준 OHLCV 스냅샷 */
  snapshotOpen?: number;
  snapshotHigh?: number;
  snapshotLow?: number;
  snapshotClose?: number;
  snapshotVolume?: number;
}

export interface AlertScheduleConfigDto {
  id?: number;
  userId?: number;
  cronExpression?: string;
  timeInterval?: string; // 시간봉 간격 (1m, 3m, 5m, 10m, 15m, 30m, 1h, 4h, 1d, 1w)
  /** 전략 조건 평가 주기(초) 3~30, 스케줄러 실행 간격 */
  strategyCheckIntervalSeconds?: number;
  enabled?: boolean;
  lastRunTime?: string;
  nextRunTime?: string;
  createdAt?: string;
  updatedAt?: string;
}

// ==================== CryptoAlert APIs ====================

/**
 * 전체 알림 목록 조회
 */
export const getAllAlerts = async (): Promise<CryptoAlertDto[]> => {
  const response = await alertApi.get<CryptoAlertDto[]>('/alerts');
  return response.data;
};

/**
 * 활성화된 알림 목록 조회
 */
export const getEnabledAlerts = async (): Promise<CryptoAlertDto[]> => {
  const response = await alertApi.get<CryptoAlertDto[]>('/alerts/enabled');
  return response.data;
};

/**
 * 알림 상세 조회
 */
export const getAlert = async (alertId: number): Promise<CryptoAlertDto> => {
  const response = await alertApi.get<CryptoAlertDto>(`/alerts/${alertId}`);
  return response.data;
};

/**
 * 심볼로 알림 조회
 */
export const getAlertBySymbol = async (symbol: string): Promise<CryptoAlertDto | null> => {
  try {
    const response = await alertApi.get<CryptoAlertDto>(`/alerts/symbol/${symbol}`);
    return response.data;
  } catch (error: any) {
    if (error.response?.status === 404) {
      return null;
    }
    throw error;
  }
};

/**
 * 알림 생성
 */
export const createAlert = async (dto: CryptoAlertDto): Promise<CryptoAlertDto> => {
  const response = await alertApi.post<CryptoAlertDto>('/alerts', dto);
  return response.data;
};

/**
 * 알림 ON/OFF 토글
 */
export const toggleAlert = async (alertId: number, enabled: boolean): Promise<CryptoAlertDto> => {
  const response = await alertApi.put<CryptoAlertDto>(
    `/alerts/${alertId}/toggle`,
    null,
    { params: { enabled } }
  );
  return response.data;
};

/**
 * 알림 삭제
 */
export const deleteAlert = async (alertId: number): Promise<void> => {
  await alertApi.delete(`/alerts/${alertId}`);
};

// ==================== AlertCondition APIs ====================

/**
 * 전역 알림 조건 목록 조회
 */
export const getGlobalConditions = async (): Promise<AlertConditionDto[]> => {
  const response = await alertApi.get<AlertConditionDto[]>('/alerts/conditions/global');
  return response.data;
};

/**
 * 알림 조건 목록 조회 (개별 종목용 - 하위 호환)
 */
export const getConditions = async (alertId: number): Promise<AlertConditionDto[]> => {
  const response = await alertApi.get<AlertConditionDto[]>(`/alerts/${alertId}/conditions`);
  return response.data;
};

/**
 * 전역 조건 추가
 */
export const addGlobalCondition = async (dto: AlertConditionDto): Promise<AlertConditionDto> => {
  const response = await alertApi.post<AlertConditionDto>('/alerts/conditions/global', dto);
  return response.data;
};

/**
 * 조건 추가 (개별 종목용 - 하위 호환)
 */
export const addCondition = async (
  alertId: number,
  dto: AlertConditionDto
): Promise<AlertConditionDto> => {
  const response = await alertApi.post<AlertConditionDto>(
    `/alerts/${alertId}/conditions`,
    dto
  );
  return response.data;
};

/**
 * 조건 수정
 */
export const updateCondition = async (
  conditionId: number,
  dto: AlertConditionDto
): Promise<AlertConditionDto> => {
  const response = await alertApi.put<AlertConditionDto>(
    `/alerts/conditions/${conditionId}`,
    dto
  );
  return response.data;
};

/**
 * 조건 삭제
 */
export const deleteCondition = async (conditionId: number): Promise<void> => {
  await alertApi.delete(`/alerts/conditions/${conditionId}`);
};

/**
 * 조건 활성화/비활성화
 */
export const toggleCondition = async (
  conditionId: number,
  enabled: boolean
): Promise<AlertConditionDto> => {
  const response = await alertApi.put<AlertConditionDto>(
    `/alerts/conditions/${conditionId}/toggle`,
    null,
    { params: { enabled } }
  );
  return response.data;
};

// ==================== AlertNotification APIs ====================

/**
 * 미읽음 알림 조회
 */
export const getUnreadNotifications = async (userId?: number): Promise<AlertNotificationDto[]> => {
  const response = await alertApi.get<AlertNotificationDto[]>(
    '/alerts/notifications/unread',
    { params: { userId } }
  );
  return response.data;
};

/**
 * 알림 목록 조회 (페이징)
 */
export const getNotifications = async (
  userId?: number,
  page: number = 0,
  size: number = 20
): Promise<{ content: AlertNotificationDto[]; totalPages: number; totalElements: number }> => {
  const response = await alertApi.get('/alerts/notifications', {
    params: { userId, page, size },
  });
  return response.data;
};

/**
 * 알림 읽음 처리
 */
export const markAsRead = async (notificationId: number): Promise<void> => {
  await alertApi.put(`/alerts/notifications/${notificationId}/read`);
};

/**
 * 모든 미읽은 알림 읽음 처리
 */
export const markAllAsRead = async (): Promise<void> => {
  await alertApi.put('/alerts/notifications/read-all');
};

/**
 * 알림 상세 정보 조회 (분석 데이터 포함)
 * @param symbol 통합 알림 등 행별 마켓(예: KRW-BTC). 지정 시 해당 종목 캔들·지표로 스냅샷 (알림 봉 시각은 동일).
 */
export const getNotificationDetail = async (
  notificationId: number,
  options?: { symbol?: string | null }
): Promise<AlertNotificationDetailDto> => {
  const sym = options?.symbol?.trim();
  const response = await alertApi.get<AlertNotificationDetailDto>(
    `/alerts/notifications/${notificationId}/detail`,
    sym ? { params: { symbol: sym } } : undefined
  );
  return response.data;
};

// ==================== AlertScheduleConfig APIs ====================

/**
 * 스케줄 설정 조회
 */
export const getScheduleConfig = async (userId?: number): Promise<AlertScheduleConfigDto> => {
  const response = await alertApi.get<AlertScheduleConfigDto>(
    '/alerts/schedule',
    { params: { userId } }
  );
  return response.data;
};

/**
 * 스케줄 설정 저장/업데이트
 */
export const saveScheduleConfig = async (
  dto: AlertScheduleConfigDto
): Promise<AlertScheduleConfigDto> => {
  const response = await alertApi.put<AlertScheduleConfigDto>('/alerts/schedule', dto);
  return response.data;
};

/**
 * 알림 삭제
 */
export const deleteNotification = async (notificationId: number): Promise<void> => {
  await alertApi.delete(`/alerts/notifications/${notificationId}`);
};

/**
 * 읽은 알림 모두 삭제
 */
export const deleteReadNotifications = async (userId?: number): Promise<void> => {
  await alertApi.delete('/alerts/notifications/read', {
    params: { userId },
  });
};

// ==================== Scheduler Service APIs ====================

export interface SchedulerStatusDto {
  running: boolean;
  status?: string;
  error?: string;
  schedulerRunning?: boolean;
  kafkaConnected?: boolean;
}

export interface SchedulerStartResultDto {
  success: boolean;
  message: string;
  manualCommand?: string;
}

/**
 * 스케줄러 서비스 상태 조회
 */
export const getSchedulerStatus = async (): Promise<SchedulerStatusDto> => {
  const response = await alertApi.get<SchedulerStatusDto>('/scheduler/status');
  return response.data;
};

/**
 * 스케줄러 서비스 시작 시도
 */
export const startScheduler = async (): Promise<SchedulerStartResultDto> => {
  const response = await alertApi.post<SchedulerStartResultDto>('/scheduler/start');
  return response.data;
};

/** Internal `/internal/alerts/evaluate` 요청 본문 */
export interface AlertEvaluateRequest {
  symbol: string;
  strategyRuleId: number;
  timeInterval: string;
  liveCandles?: Record<string, unknown>[];
  useLiveCandleTail?: boolean;
}

export interface AlertEvaluateResponse {
  symbol?: string;
  strategyRuleId?: number;
  conditionMet: boolean;
  message?: string;
}

/**
 * 알림 전략 조건 평가 (스케줄러와 동일 백엔드 경로)
 * `liveCandles`가 있으면 WS 버퍼 기준, 없으면 서버 Redis/REST 200봉.
 */
export const evaluateAlertStrategy = async (body: AlertEvaluateRequest): Promise<AlertEvaluateResponse> => {
  const response = await alertApi.post<AlertEvaluateResponse>('/internal/alerts/evaluate', body);
  return response.data;
};

/**
 * 테스트 알림 생성 (파이프라인 검증용)
 * Internal API - 첫 번째 종목으로 테스트 알림 생성
 */
export const createTestNotification = async (): Promise<AlertNotificationDto> => {
  const response = await alertApi.post<AlertNotificationDto>('/internal/alerts/test');
  return response.data;
};

/**
 * 알림 읽음 처리
 */
export const markNotificationAsRead = async (notificationId: number): Promise<void> => {
  await alertApi.put(`/alerts/notifications/${notificationId}/read`);
};

export default {
  getAllAlerts,
  getEnabledAlerts,
  getAlert,
  getAlertBySymbol,
  createAlert,
  toggleAlert,
  deleteAlert,
  getGlobalConditions,
  getConditions,
  addGlobalCondition,
  addCondition,
  updateCondition,
  deleteCondition,
  toggleCondition,
  getUnreadNotifications,
  getNotifications,
  markAsRead,
  getScheduleConfig,
  saveScheduleConfig,
  deleteNotification,
  deleteReadNotifications,
  markNotificationAsRead,
};

