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

export interface FolderInfo {
  path: string;
  name: string;
  type: string;
  fileCount: number;
  totalSize: number;
  processedCount: number;
  pendingCount: number;
  hasChildren: boolean;  // 하위 폴더/파일 존재 여부 (lazy loading용)
  /** 업비트 crix-data (type FILE) */
  downloadUrl?: string;
  children?: FolderInfo[];
}

export interface FileInfo {
  filePath: string;
  fileName: string;
  market: string;
  timeUnit: string;
  dataDate: string;
  year: number;
  fileSize: number;
  isProcessed: boolean;
  processedAt?: string;
  status?: string;
  recordCount?: number;
}

export interface DataCollectionRequest {
  targetPath?: string;
  markets?: string[];
  timeUnits?: string[];
  processAll?: boolean;
  maxFiles?: number;
}

export interface DataCollectionStatus {
  isRunning: boolean;
  totalFiles: number;
  processedFiles: number;
  successCount: number;
  failCount: number;
  skipCount: number;
  totalRecords: number;
  progressPercent: number;
  currentFile: string;
  startTime: string;
  estimatedEndTime?: string;
  recentLogs: string[];
  errorMessage?: string;
  // 종목 기반 진행률
  totalMarkets: number;
  processedMarkets: number;
  currentMarket: string;
}

export interface DataUpdateHistory {
  id: number;
  filePath: string;
  fileName: string;
  market: string;
  timeUnit: string;
  dataDate: string;
  year: number;
  recordCount: number;
  fileSize: number;
  status: string;
  errorMessage?: string;
  processedAt: string;
  processingDurationMs: number;
}

export interface DataCollectionSummary {
  totalProcessedFiles: number;
  totalRecords: number;
  successCount: number;
  failCount: number;
  skipCount: number;
  lastProcessedAt?: string;
  marketCounts: Record<string, number>;
  timeUnitCounts: Record<string, number>;
}

export interface UpbitArchiveImportResult {
  success: boolean;
  message: string;
  recordCount: number;
  durationMs: number;
  logicalPath?: string;
  batchTotalZips?: number;
  batchSuccessZips?: number;
  batchFailZips?: number;
  batchSkipZips?: number;
}

export interface UpbitImportProgress {
  jobId: string;
  phase: string;
  percent: number;
  message: string;
  done: boolean;
  /** 완료 시 */
  result?: UpbitArchiveImportResult;
  /** 날짜·봉 배치 */
  totalPlanned?: number;
  currentIndex?: number;
}

export interface UpbitImportStartResult {
  jobId: string;
}

export interface UpbitByDateBatchPreview {
  year: number;
  month: number;
  /** 있으면 해당 일만, 없으면 월 전체(가능한 일) */
  day?: number | null;
  marketCount: number;
  totalZips: number;
  message: string;
}

export const dataCollectionApi = {
  getFolderStructure: async (path?: string): Promise<FolderInfo> => {
    const response = await axios.get(`${API_BASE_URL}/data-collection/folders`, {
      params: { path },
    });
    return response.data;
  },

  getPendingFiles: async (path?: string, limit?: number): Promise<FileInfo[]> => {
    const response = await axios.get(`${API_BASE_URL}/data-collection/files`, {
      params: { path, limit },
    });
    return response.data;
  },

  startCollection: async (request: DataCollectionRequest): Promise<DataCollectionStatus> => {
    const response = await axios.post(`${API_BASE_URL}/data-collection/process`, request);
    return response.data;
  },

  stopCollection: async (): Promise<DataCollectionStatus> => {
    const response = await axios.post(`${API_BASE_URL}/data-collection/stop`);
    return response.data;
  },

  getStatus: async (): Promise<DataCollectionStatus> => {
    const response = await axios.get(`${API_BASE_URL}/data-collection/status`);
    return response.data;
  },

  getHistory: async (limit?: number): Promise<DataUpdateHistory[]> => {
    const response = await axios.get(`${API_BASE_URL}/data-collection/history`, {
      params: { limit },
    });
    return response.data;
  },

  getSummary: async (): Promise<DataCollectionSummary> => {
    const response = await axios.get(`${API_BASE_URL}/data-collection/summary`);
    return response.data;
  },

  /** 업비트 crix-data — 가상 경로 한 단계 자식(마켓/봉/연/월, 월은 일 zip 목록) */
  browseUpbitArchive: async (path?: string): Promise<FolderInfo> => {
    const response = await axios.get(`${API_BASE_URL}/data-collection/upbit-archive/browse`, {
      params: { path: path || 'upbit-site' },
    });
    return response.data;
  },

  importUpbitArchive: async (path: string, reprocess: boolean): Promise<UpbitArchiveImportResult> => {
    const response = await axios.post(`${API_BASE_URL}/data-collection/upbit-archive/import`, {
      path,
      reprocess,
    });
    return response.data;
  },

  startUpbitImport: async (path: string, reprocess: boolean): Promise<UpbitImportStartResult> => {
    const response = await axios.post(`${API_BASE_URL}/data-collection/upbit-archive/import/start`, {
      path,
      reprocess,
    });
    return response.data;
  },

  getUpbitImportProgress: async (jobId: string): Promise<UpbitImportProgress> => {
    const response = await axios.get(
      `${API_BASE_URL}/data-collection/upbit-archive/import/progress/${encodeURIComponent(jobId)}`
    );
    return response.data;
  },

  previewUpbitByDate: async (params: {
    year: number;
    month: number;
    timeUnits: string[];
    day?: number;
  }): Promise<UpbitByDateBatchPreview> => {
    const search = new URLSearchParams();
    search.set('year', String(params.year));
    search.set('month', String(params.month));
    if (params.day != null && params.day > 0) {
      search.set('day', String(params.day));
    }
    for (const t of params.timeUnits) {
      search.append('timeUnits', t);
    }
    const response = await axios.get(
      `${API_BASE_URL}/data-collection/upbit-archive/by-date/preview?${search.toString()}`
    );
    return response.data;
  },

  startUpbitImportByDate: async (body: {
    year: number;
    month: number;
    timeUnits: string[];
    reprocess: boolean;
    day?: number;
  }): Promise<UpbitImportStartResult> => {
    const response = await axios.post(
      `${API_BASE_URL}/data-collection/upbit-archive/by-date/import/start`,
      {
        year: body.year,
        month: body.month,
        timeUnits: body.timeUnits,
        reprocess: body.reprocess,
        ...(body.day != null && body.day > 0 ? { day: body.day } : {}),
      }
    );
    return response.data;
  },
};

