const Router = require('@koa/router')

const { db } = require('../db')
const { validate_fid, gen_count_body } = require('./gd')
const { send_count, send_help, send_choice, send_task_info, sm, extract_fid, extract_from_text, reply_cb_query, tg_copy, send_all_tasks, send_bm_help, get_target_by_alias, send_all_bookmarks, set_bookmark, unset_bookmark, clear_tasks, send_task_help, rm_task } = require('./tg')

const { AUTH, ROUTER_PASSKEY, TG_IPLIST } = require('../config')
const { tg_whitelist } = AUTH

const COPYING_FIDS = {}
const counting = {}
const router = new Router()

router.get('/api/gdurl/count', async ctx => {
  if (!ROUTER_PASSKEY) return ctx.body = 'gd-utils-cht 成功啟動'
  const { query, headers } = ctx.request
  let { fid, type, update, passkey } = query
  if (passkey !== ROUTER_PASSKEY) return ctx.body = 'invalid passkey'
  if (!validate_fid(fid)) throw new Error('無效的分享ID')

  let ua = headers['user-agent'] || ''
  ua = ua.toLowerCase()
  type = (type || '').toLowerCase()
  // todo type=tree
  if (!type) {
    if (ua.includes('curl')) {
      type = 'curl'
    } else if (ua.includes('mozilla')) {
      type = 'html'
    } else {
      type = 'json'
    }
  }
  if (type === 'html') {
    ctx.set('Content-Type', 'text/html; charset=utf-8')
  } else if (['json', 'all'].includes(type)) {
    ctx.set('Content-Type', 'application/json; charset=UTF-8')
  }
  ctx.body = await gen_count_body({ fid, type, update, service_account: true })
})

router.post('/api/gdurl/tgbot', async ctx => {
  const { body } = ctx.request
  console.log('ctx.ip', ctx.ip) // 可以只允许tg服务器的ip
  console.log('tg message:', body)
  if (TG_IPLIST && !TG_IPLIST.includes(ctx.ip)) return ctx.body = 'invalid ip'
  ctx.body = '' // 早点释放连接
  const message = body.message || body.edited_message

  const { callback_query } = body
  if (callback_query) {
    const { id, data } = callback_query
    const chat_id = callback_query.from.id
    const [action, fid, target] = data.split(' ')
    if (action === 'count') {
      if (counting[fid]) return sm({ chat_id, text: fid + ' 正在統計，請稍候' })
      counting[fid] = true
      send_count({ fid, chat_id }).catch(err => {
        console.error(err)
        sm({ chat_id, text: fid + ' 統計失敗：' + err.message })
      }).finally(() => {
        delete counting[fid]
      })
    } else if (action === 'copy') {
      if (COPYING_FIDS[fid]) return sm({ chat_id, text: `正在處理 ${fid} 的複製命令` })
      COPYING_FIDS[fid] = true
      tg_copy({ fid, target: get_target_by_alias(target), chat_id }).then(task_id => {
        task_id && sm({ chat_id, text: `開始複製，任務ID: ${task_id} 可輸入 /task ${task_id} 查詢進度` })
      }).finally(() => COPYING_FIDS[fid] = false)
    }
    return reply_cb_query({ id, data }).catch(console.error)
  }

  const chat_id = message && message.chat && message.chat.id
  const text = message && message.text && message.text.trim()
  let username = message && message.from && message.from.username
  username = username && String(username).toLowerCase()
  let user_id = message && message.from && message.from.id
  user_id = user_id && String(user_id).toLowerCase()
  if (!chat_id || !text || !tg_whitelist.some(v => {
    v = String(v).toLowerCase()
    return v === username || v === user_id
  })) return console.warn('異常請求')

  const fid = extract_fid(text) || extract_from_text(text)
  const no_fid_commands = ['/task', '/help', '/bm']
  if (!no_fid_commands.some(cmd => text.startsWith(cmd)) && !validate_fid(fid)) {
    return sm({ chat_id, text: '未辨識到分享ID' })
  }
  if (text.startsWith('/help')) return send_help(chat_id)
  if (text.startsWith('/bm')) {
    const [cmd, action, alias, target] = text.split(' ').map(v => v.trim())
    if (!action) return send_all_bookmarks(chat_id)
    if (action === 'set') {
      if (!alias || !target) return sm({ chat_id, text: '標籤名和dstID不能為空' })
      if (alias.length > 24) return sm({ chat_id, text: '標籤名請勿超過24个英文字符' })
      if (!validate_fid(target)) return sm({ chat_id, text: 'dstID格式錯誤' })
      set_bookmark({ chat_id, alias, target })
    } else if (action === 'unset') {
      if (!alias) return sm({ chat_id, text: '標籤名不能為空' })
      unset_bookmark({ chat_id, alias })
    } else {
      send_bm_help(chat_id)
    }
  } else if (text.startsWith('/count')) {
    if (counting[fid]) return sm({ chat_id, text: fid + ' 正在統計，請稍候' })
    try {
      counting[fid] = true
      const update = text.endsWith(' -u')
      await send_count({ fid, chat_id, update })
    } catch (err) {
      console.error(err)
      sm({ chat_id, text: fid + ' 統計失敗：' + err.message })
    } finally {
      delete counting[fid]
    }
  } else if (text.startsWith('/copy')) {
    let target = text.replace('/copy', '').replace(' -u', '').trim().split(' ').map(v => v.trim())[1]
    target = get_target_by_alias(target) || target
    if (target && !validate_fid(target)) return sm({ chat_id, text: `目標ID ${target} 格式不正確` })
    const update = text.endsWith(' -u')
    tg_copy({ fid, target, chat_id, update }).then(task_id => {
      task_id && sm({ chat_id, text: `開始複製，任務ID: ${task_id} 可輸入 /task ${task_id} 查詢進度` })
    })
  } else if (text.startsWith('/task')) {
    let task_id = text.replace('/task', '').trim()
    if (task_id === 'all') {
      return send_all_tasks(chat_id)
    } else if (task_id === 'clear') {
      return clear_tasks(chat_id)
    } else if (task_id === '-h') {
      return send_task_help(chat_id)
    } else if (task_id.startsWith('rm')) {
      task_id = task_id.replace('rm', '')
      task_id = parseInt(task_id)
      if (!task_id) return send_task_help(chat_id)
      return rm_task({ task_id, chat_id })
    }
    task_id = parseInt(task_id)
    if (!task_id) {
      const running_tasks = db.prepare('select id from task where status=?').all('copying')
      if (!running_tasks.length) return sm({ chat_id, text: '目前沒有執行中的任務' })
      return running_tasks.forEach(v => send_task_info({ chat_id, task_id: v.id }).catch(console.error))
    }
    send_task_info({ task_id, chat_id }).catch(console.error)
  } else if (text.includes('drive.google.com/') || validate_fid(text)) {
    return send_choice({ fid: fid || text, chat_id }).catch(console.error)
  } else {
    sm({ chat_id, text: '暫不支持此命令' })
  }
})

module.exports = router
