import { TguApiError } from '../model/tguTypes'
import { apiFetch } from './apiFetch'

/**
 * Карта приоритетов ячеек сетки заданий (pcp-request-service, GET /v1/cells/priority-map).
 * Это тот же источник, по которому комплексный план считает покрытие заявок — отдаёт только
 * ячейки, на которые спроецированы заявки (с их важностью и контуром), а не весь каталог сетки.
 * Используется на вкладке «Комплексный план» для тепловой карты приоритетов.
 */
const BASE = '/api/pcp-request/v1'

/**
 * Минимальная важность ячейки, ниже которой ячейку не возвращаем — тот же порог, что и в
 * комплексном сервисе (REQUEST_GRID_MIN_IMPORTANCE), чтобы тепловая карта совпадала с тем,
 * что реально участвует в расчёте.
 */
export const HEATMAP_MIN_IMPORTANCE = 0.001

/** Фрагмент заявки внутри ячейки сетки приоритетов. */
export type PriorityCellRequest = {
  requestId: string
  /** Контур фрагмента заявки внутри ячейки, WKT POLYGON. */
  contour: string
  /** Процент покрытия ячейки фрагментом заявки. */
  coveragePercent: number
  /** Snapshot важности заявки из request_cells. */
  importance: number
}

/** Ячейка сетки приоритетов: центр, важность, контур (WKT POLYGON) и фрагменты заявок. */
export type PriorityCell = {
  cellNum: number
  latitude: number
  longitude: number
  importance: number
  /** Контур ячейки, WKT POLYGON (lon lat, ...). */
  contour: string
  /** Фрагменты заявок, пересекающие ячейку. */
  requests: PriorityCellRequest[]
}

/**
 * Загрузить карту приоритетов ячеек (ячейки с важностью и контуром) для тепловой карты.
 * @param minImportance Порог важности (по умолчанию {@link HEATMAP_MIN_IMPORTANCE}).
 *
 * @returns Список ячеек сетки с важностью и контурами.
 */
export async function fetchPriorityCells(
  minImportance: number = HEATMAP_MIN_IMPORTANCE,
): Promise<PriorityCell[]> {
  const params = new URLSearchParams({ minImportance: String(minImportance) })
  const url = `${BASE}/cells/priority-map?${params}`
  let response: Response
  try {
    response = await apiFetch(url, { method: 'GET', headers: { Accept: 'application/json' } })
  } catch {
    throw new TguApiError('Не удалось подключиться к сервису заданий.', 'network')
  }
  const text = await response.text()
  if (!response.ok) {
    throw new TguApiError(
      extractErrorText(text) || 'Не удалось загрузить карту приоритетов.',
      'http',
      response.status,
    )
  }
  if (!text.trim()) return []
  const parsed = JSON.parse(text) as { items?: PriorityCell[] }
  return parsed.items ?? []
}

function extractErrorText(body: string): string {
  const trimmed = body.trim()
  if (!trimmed) return ''
  try {
    const parsed = JSON.parse(trimmed) as Record<string, unknown>
    for (const field of ['message', 'error', 'reason', 'detail']) {
      const value = parsed[field]
      if (typeof value === 'string' && value.trim()) return value
    }
  } catch {
    return trimmed
  }
  return trimmed
}
