// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: green; icon-glyph: newspaper;
// Version 1.0.2

////////////////////////////////////////////////////////////////////////////////
//////////////////////////         User-Config         /////////////////////////
////////////////////////////////////////////////////////////////////////////////

// How many minutes should the cache be valid
const cacheMinutes = 60

////////////////////////////////////////////////////////////////////////////////
//////////////////////////         Dev Settings         ////////////////////////
////////////////////////////////////////////////////////////////////////////////

const debug = false
config.widgetFamily = config.widgetFamily || 'medium'

////////////////////////////////////////////////////////////////////////////////
//////////////////////////         System Settings         /////////////////////
////////////////////////////////////////////////////////////////////////////////

const spacingBetweenLinks = 5

const numberOfArticles = {  
  small: 1,
  medium: 6,
  large: 15
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

var today = new Date()

// Set up the file manager.
const files = FileManager.local()

// Set up cache
const cachePath = files.joinPath(files.cacheDirectory(), "widget-devto-" + config.widgetFamily)
const cacheExists = files.fileExists(cachePath)
const cacheDate = cacheExists ? files.modificationDate(cachePath) : 0

// Get Data
let result
let lastUpdate
try {
  // If cache exists and it's been less than 30 minutes since last request, use cached data.
  if (cacheExists && (today.getTime() - cacheDate.getTime()) < (cacheMinutes * 60 * 1000)) {
    console.log("Get from Cache")
    result = JSON.parse(files.readString(cachePath))
    lastUpdate = cacheDate
  } else {
    console.log("Get from API")
    const req = new Request(`https://dev.to/search/feed_content?per_page=${numberOfArticles[config.widgetFamily]}&page=0&sort_by=hotness_score&sort_direction=desc&approved=&class_name=Article`)
  
    result = (await req.loadJSON()).result
    lastUpdate = today
    console.log("Write Data to Cache")
    try {
      files.writeString(cachePath, JSON.stringify(result))
    } catch (e) {
      console.log("Creating Cache failed!")
      console.log(e)
    }
  }
} catch (e) {
  console.error(e)
  if (cacheExists) {
    console.log("Get from Cache")
    result = JSON.parse(files.readString(cachePath))
    lastUpdate = cacheDate
  } else {
    console.log("No fallback to cache possible. Due to missing cache.")
  }
}

if (debug) {  
  console.log(JSON.stringify(result, null, 2))
}

const widget = new ListWidget()
if (config.widgetFamily !== 'small') {
  widget.addSpacer(0)

  let firstLineStack = widget.addStack()
  
  let provider = firstLineStack.addText("Dev.to")
  provider.font = Font.boldSystemFont(12)
  
    // Last Update
  firstLineStack.addSpacer()
  lastUpdateStack = firstLineStack.addStack()
  lastUpdateStack.layoutVertically()
  lastUpdateStack.addSpacer(3)
  let lastUpdateText = lastUpdateStack.addDate(lastUpdate)
  lastUpdateText.font = Font.systemFont(8)
  lastUpdateText.rightAlignText()
  lastUpdateText.applyTimeStyle()
  widget.addSpacer(8)
  
  const stack = widget.addStack()  
  stack.layoutVertically()
  stack.spacing = spacingBetweenLinks

  result.forEach((r) => {  
    const row = stack.addStack()
    row.layoutHorizontally()
    const text = row.addText(`- ${r.title}`)
    text.font = Font.systemFont(11)
    text.lineLimit = 1
    row.url = `https://dev.to${r.path}`
  })
  widget.addSpacer()
} else {
  widget.setPadding(0, 0, 0, 0)
  widget.addSpacer(0)

  let firstLineStack = widget.addStack()
  firstLineStack.setPadding(5, 10, 5, 10)
  firstLineStack.backgroundColor = Color.dynamic(new Color('EDEDED', 0.7), new Color('111111', 0.7))
  
  let provider = firstLineStack.addText("Dev.to")
  provider.font = Font.boldSystemFont(12)
  
  // Last Update
  firstLineStack.addSpacer()
  lastUpdateStack = firstLineStack.addStack()
  lastUpdateStack.layoutVertically()
  lastUpdateStack.addSpacer(3)
  let lastUpdateText = lastUpdateStack.addDate(lastUpdate)
  lastUpdateText.font = Font.systemFont(8)
  lastUpdateText.rightAlignText()
  lastUpdateText.applyTimeStyle()
  widget.addSpacer()
  
  const article = result[0]
  if (article.main_image) {  
    const imageReq = new Request(article.main_image)
    widget.backgroundImage = (await imageReq.loadImage())  
  }
  
  const stack = widget.addStack()
  stack.layoutHorizontally()
  stack.addSpacer()
  stack.setPadding(10, 10, 10, 10)
  stack.backgroundColor = Color.dynamic(new Color('EDEDED', 0.7), new Color('111111', 0.7))
  
  const text = stack.addText(article.title)
  text.font = Font.boldSystemFont(12)
  stack.addSpacer()
  
  widget.url = `https://dev.to${article.path}`
  widget.addSpacer(0)
}



if (!config.runsInWidget) {
  switch (config.widgetFamily) {
    case 'small': await widget.presentSmall(); break;
    case 'medium': await widget.presentMedium(); break;
    case 'large': await widget.presentLarge(); break;
  }
} else {
  Script.setWidget(widget)
}
Script.complete()