class taskFunc {
  relDateString(d, luxon) {
    if (!(d instanceof luxon.DateTime)) return '–'
    const now = luxon.DateTime.now()
    const days = Math.ceil(d.diff(now, 'days').days)
    if (days < 0) return 'Overdue ' + d.toFormat('L/d')
    if (days === 0) return 'Today'
    if (days === 1) return 'Tomorrow'
    if (days < 7) return d.toFormat('cccc')
    return d.toFormat('ccc L/d')
  }

  getButtonStrings(status) {
    const completed = status === 'Completed'
    const btnStr = completed ? 'Undo' : 'Done'
    const updateStr = completed ? 'To-Do' : 'Completed'
    return { btnStr, updateStr }
  }

  getCustomLink(name, target) {
    return `[[${target}|${name}]]`
  }

  getTodayTasks(args) {
    const { luxon, dv, that, theme } = args
    const finalDate = luxon.DateTime.now().toISODate() //?? dv.current().file.name
    return this.getTasksTable({
      ...args,
      filterFn: t => this.getPoint(t, "type") == 'Task' && this.getPoint(t, "status") != 'Completed' && this.getPoint(t, "duedate") && this.getPoint(t, "duedate")?.hasSame(luxon.DateTime.fromISO(finalDate), 'day')
    })
  }
	
	getAllTasks(args) {
    const { luxon, dv, that, theme } = args
    return this.getTasksTable({
      ...args,
      filterFn: t => this.getPoint(t, "type") == 'Task' && this.getPoint(t, "reviewdate")
    })
  }

  getOverdueTasks(args) {
    const { luxon, dv, that, theme } = args
    const finalDate = luxon.DateTime.now().toISODate() //date ?? dv.current().file.name
    return this.getTasksTable({
      ...args,
      filterFn: t => this.getPoint(t, "type") == 'Task' && this.getPoint(t, "duedate") && this.getPoint(t, "duedate") < luxon.DateTime.fromISO(finalDate) && this.getPoint(t, "status") != 'Completed'
    })
  }
	
	getLateReviewTasks(args) {
    const { luxon, dv, that, theme } = args
    const finalDate = luxon.DateTime.now().toISODate() //date ?? dv.current().file.name
    return this.getTasksTable({
      ...args,
      filterFn: t => this.getPoint(t, "type") == 'Task' && this.getPoint(t, "reviewdate") && this.getPoint(t, "reviewdate") < luxon.DateTime.fromISO(finalDate) && this.getPoint(t, "status") != 'Completed'
    })
  }

  getTasksNoDueDate(args) {
    return this.getTasksTable({
      ...args,
//      prependText: 'No Due Date',
      filterFn: t => this.getPoint(t, "type") == 'Task' && !this.getPoint(t, "duedate")
    })
  }
	
	getPriorityTasks(args) {
    const { luxon, dv, that, theme } = args
    return this.getTasksTable({
      ...args,
      filterFn: t => this.getPoint(t, "type") == 'Task' && this.getPoint(t, "reviewdate") && this.getPoint(t, "priority") == 'High'
    })
  }

  getTasksTable(args) {
    const {
      that,
      app,
      dv,
      luxon,
			theme,
      getSortProp = t => this.getPoint(t, "reviewdate"),
      sortOrder = 'asc',
      filterFn = t => {this.getPoint(t, "type") == 'Task'},
      completedCol = false,
      prependHeaderLevel = 3,
      prependText
    } = args;
    const { metaedit, buttons } = app.plugins.plugins
    const { update } = metaedit.api
    const { createButton } = buttons
		const pFilter = '#' + theme


    const dueStr = completedCol ? 'Completed' : 'Review Date';
    const pages = dv.pages(pFilter).sort(getSortProp, sortOrder).where(filterFn)
    if (pages.length === 0) {
      // console.log('Empty dataview:', args)
      return dv.el('b', '🗓 ✅ No pending task')
    }

    if (prependText) {
      dv.header(prependHeaderLevel, prependText)
    }

    dv.table(["Name", "Category", "Priority", dueStr, "", ""], pages
      .map(t => {
        const { btnStr, updateStr } = this.getButtonStrings(this.getPoint(t, "status"))
        return [
          this.getCustomLink(t.file.name, t.file.name),
          this.getPoint(t, "tag"),
					this.getPoint(t, "priority"),
          this.relDateString(this.getPoint(t, "reviewdate"), luxon),
          createButton({
            app,
            el: that.container,
            args: { name: btnStr },
            clickOverride: { click: update, params: ['Status', updateStr, t.file.path] }
          }),
        ]
      })
    )
  }
	
	getPoint(p, datapoint) {
		
		let result = null
		
		switch(datapoint) {
			case 'reviewdate':
				result = p.NextReviewDate
			break;
			case 'duedate':
				result = p.DueDate
			break;
			case 'startdate':
				result = p.StartDate
			break;
			case 'priority':
				result = p.Priority
			break;
			case 'timestamp':
				result = p.TimeStamp
			break;
			case 'status':
				result = p.Status
			break;
			case 'type':
				result = p.DocType
			break;
			case 'createddate':
				result = p.Date
			break;
			case 'tag':
				result = p.Tag
			break;
			case 'hierarchy':
				result = p.Hierarchy
			break;
			case 'alias':
				result = p.Alias
			break;
			case 'location':
				result = p.location
			break;
		}
		
		return result
		
	}
}
