const axios = require('axios')
const cheerio = require('cheerio')
const dayjs = require('dayjs')
const timezone = require('dayjs/plugin/timezone')
const utc = require('dayjs/plugin/utc')
const customParseFormat = require('dayjs/plugin/customParseFormat')
const debug = require('debug')('site:rotana.net')

dayjs.extend(timezone)
dayjs.extend(utc)
dayjs.extend(customParseFormat)

const headers = {
  'User-Agent':
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 OPR/104.0.0.0'
}
const cookies = {}

module.exports = {
  site: 'rotana.net',
  days: 2,
  url({ channel }) {
    return `https://rotana.net/${channel.lang}/streams?channel=${channel.site_id}&tz=`
  },
  request: {
    headers,
    timeout: 15000
  },
  async parser({ content, headers, channel, date }) {
    const programs = []
    if (!cookies[channel.lang]) {
      cookies[channel.lang] = parseCookies(headers)
    }

    const items = parseItems(content, date)
    for (const item of items) {
      const program = await parseProgram(item, channel)
      if (program) {
        programs.push(program)
      }
    }

    return programs
  },
  async channels({ lang = 'en' }) {
    const result = await axios
      .get(`https://rotana.net/api/channels`)
      .then(response => response.data)
      .catch(console.error)

    return result.data.map(item => {
      return {
        lang,
        site_id: item.id,
        name: item.name[lang]
      }
    })
  }
}

async function parseProgram(item, channel, options = {}) {
  options = options || {}
  const deep = options.deep !== undefined ? options.deep : true
  const raw = options.raw !== undefined ? options.raw : false
  const top = item.find('.iq-accordion-block')
  const info = top.find('.iq-accordion-title .big-title span')
  if (info.length) {
    const [time, title] = info.text().split('\n')
    const [d, m, y] = item._date.split('-')
    const start = dayjs.tz(`${y}-${m}-${d} ${time.trim()}`, 'YYYY-MM-DD HH:mm', 'Asia/Riyadh')
    let description, image, stop
    if (deep) {
      const pid = top.attr('id').split('-')[1]
      if (pid) {
        const url = `https://rotana.net/${channel.lang}/streams?channel=${channel.site_id}&itemId=${pid}`
        const params = {
          headers: Object.assign({}, headers, { 'X-Requested-With': 'XMLHttpRequest' }),
          Cookie: cookies[channel.lang]
        }
        debug(`fetching description ${url}`)
        const result = await axios
          .get(url, params)
          .then(response => response.data)
          .catch(console.error)

        const $ = cheerio.load(result)
        const details = $('.trending-info div > span')
        if (details.length) {
          description = details.text().split('\n')[3].trim()
        }
        const img = $('.row > div > img')
        if (img.length) {
          image = img.attr('src')
        }
      }
      if (item._next) {
        const next = await parseProgram(item._next, channel, { deep: false, raw: true })
        if (next.start) {
          stop = next.start
        }
      }
    }
    return {
      title: title?.trim(),
      description: description?.trim(),
      image,
      start: raw ? start : start?.toISOString(),
      stop: raw ? stop : stop?.toISOString()
    }
  }
}

function parseItems(content, date) {
  const result = []
  const $ = cheerio.load(content)

  const expectedId = `item-${date.format('DD-MM-YYYY')}`
  let lastId
  $('.hour > div').each((_, item) => {
    const $item = $(item)
    if ($item.hasClass('bg')) {
      lastId = $item.attr('id')
    } else if ($item.hasClass('iq-accordion')) {
      $item._date = lastId.substr(lastId.indexOf('-') + 1)
      // is date match?
      if (lastId === expectedId) {
        // set next item
        if (result.length) {
          result[result.length - 1]._next = $item
        }
        result.push($item)
      } else if (result.length && !result[result.length - 1]._next) {
        // set next item
        result[result.length - 1]._next = $item
      }
    }
  })

  return result
}

function parseCookies(headers) {
  const cookies = []
  if (headers && Array.isArray(headers['set-cookie'])) {
    headers['set-cookie'].forEach(cookie => {
      cookies.push(cookie.split('; ')[0])
    })
  }
  return cookies.length ? cookies.join('; ') : null
}
