import { wingPool } from '../db/wingDb.js'

export interface MapBaseItem {
  mapSn: number;
  mapKey: string;
  mapNm: string;
  mapLevelCd: string | null;
  mapSrc: string | null;
  mapDc: string | null;
  useYn: string;
  regId: string | null;
  regNm: string | null;
  regDtm: string | null;
}

export interface MapTypeItem {
  mapKey: string;
  mapNm: string;
  mapLevelCd: string | null;
}

function rowToItem(r: Record<string, unknown>): MapBaseItem {
  return {
    mapSn: r.map_sn as number,
    mapKey: r.map_key as string,
    mapNm: r.map_nm as string,
    mapLevelCd: (r.map_level_cd as string) ?? null,
    mapSrc: (r.map_src as string) ?? null,
    mapDc: (r.map_dc as string) ?? null,
    useYn: r.use_yn as string,
    regId: (r.reg_id as string) ?? null,
    regNm: (r.reg_nm as string) ?? null,
    regDtm: r.reg_dtm ? new Date(r.reg_dtm as string).toISOString().slice(0, 10) : null,
  }
}

export async function listMapBase(
  page = 1,
  limit = 20
): Promise<{ rows: MapBaseItem[]; total: number }> {
  const offset = (page - 1) * limit
  const countResult = await wingPool.query(`SELECT COUNT(*) AS cnt FROM wing.MAP_BASE_DATA WHERE DEL_YN = 'N'`)
  const total = parseInt(countResult.rows[0].cnt as string, 10)

  const { rows } = await wingPool.query(
    `SELECT MAP_SN, MAP_KEY, MAP_NM, MAP_LEVEL_CD, MAP_SRC, MAP_DC,
            USE_YN, REG_ID, REG_NM, REG_DTM
     FROM wing.MAP_BASE_DATA
     WHERE DEL_YN = 'N'
     ORDER BY MAP_SN
     LIMIT $1 OFFSET $2`,
    [limit, offset]
  )
  return { rows: rows.map(rowToItem), total }
}

export async function getActiveMapTypes(): Promise<MapTypeItem[]> {
  const { rows } = await wingPool.query(
    `SELECT MAP_KEY, MAP_NM, MAP_LEVEL_CD
     FROM wing.MAP_BASE_DATA
     WHERE USE_YN = 'Y' AND DEL_YN = 'N'
     ORDER BY MAP_SN`
  )
  return rows.map((r: Record<string, unknown>) => ({
    mapKey: r.map_key as string,
    mapNm: r.map_nm as string,
    mapLevelCd: (r.map_level_cd as string) ?? null,
  }))
}

export async function createMapBase(data: {
  mapKey: string;
  mapNm: string;
  mapLevelCd?: string;
  mapSrc?: string;
  mapDc?: string;
  useYn?: string;
  regId?: string;
  regNm?: string;
}): Promise<MapBaseItem> {
  const { rows } = await wingPool.query(
    `INSERT INTO wing.MAP_BASE_DATA
       (MAP_KEY, MAP_NM, MAP_LEVEL_CD, MAP_SRC, MAP_DC, USE_YN, REG_ID, REG_NM)
     VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
     RETURNING *`,
    [
      data.mapKey,
      data.mapNm,
      data.mapLevelCd ?? null,
      data.mapSrc ?? null,
      data.mapDc ?? null,
      data.useYn ?? 'Y',
      data.regId ?? null,
      data.regNm ?? null,
    ]
  )
  return rowToItem(rows[0])
}

export async function updateMapBase(
  mapSn: number,
  data: {
    mapKey?: string;
    mapNm?: string;
    mapLevelCd?: string | null;
    mapSrc?: string | null;
    mapDc?: string | null;
    useYn?: string;
  }
): Promise<MapBaseItem | null> {
  const fields: string[] = []
  const params: unknown[] = []
  let idx = 1

  if (data.mapKey !== undefined) { fields.push(`MAP_KEY = $${idx++}`); params.push(data.mapKey) }
  if (data.mapNm !== undefined) { fields.push(`MAP_NM = $${idx++}`); params.push(data.mapNm) }
  if (data.mapLevelCd !== undefined) { fields.push(`MAP_LEVEL_CD = $${idx++}`); params.push(data.mapLevelCd) }
  if (data.mapSrc !== undefined) { fields.push(`MAP_SRC = $${idx++}`); params.push(data.mapSrc) }
  if (data.mapDc !== undefined) { fields.push(`MAP_DC = $${idx++}`); params.push(data.mapDc) }
  if (data.useYn !== undefined) { fields.push(`USE_YN = $${idx++}`); params.push(data.useYn) }

  if (fields.length === 0) return null
  fields.push(`MDFCN_DTM = NOW()`)

  params.push(mapSn)
  const { rows } = await wingPool.query(
    `UPDATE wing.MAP_BASE_DATA SET ${fields.join(', ')} WHERE MAP_SN = $${idx} RETURNING *`,
    params
  )
  if (rows.length === 0) return null
  return rowToItem(rows[0])
}

export async function deleteMapBase(mapSn: number): Promise<boolean> {
  const { rowCount } = await wingPool.query(
    `UPDATE wing.MAP_BASE_DATA SET DEL_YN = 'Y', MDFCN_DTM = NOW() WHERE MAP_SN = $1`,
    [mapSn]
  )
  return (rowCount ?? 0) > 0
}
