// Change to true to see a preview of your widget.
const testMode = true

// Optionally specify the size of your widget preview.
const widgetPreview = "large"

/* -- GREETING AND DATE -- */

// Optionally show a greeting based on the time of day.
const showGreeting = true

// Choose the date style. "iOS" matches the default calendar app (like: THURSDAY 29)
// Or, use docs.scriptable.app/dateformatter to write your own format.
const dateDisplay = "EEEE"

/* -- EVENTS -- */

// Change to false to hide events.
const showEvents = true

// Choose whether to show all-day events.
const showAllDay = false

// Specify how many events to show.
const numberOfEvents = 4

// Optionally show tomorrow's events.
const showTomorrow = false

// Write a message when there are no events, or change to "" for blank.
const noEventMessage = "Keep happy and keep smiling."

/* -- SPACING -- */

// Can be top, middle, or bottom.
const verticalAlignment = "middle"

// Can be left, center, or right.
const horizontalAlignment = "left"

// The spacing between each element. 
const elementSpacing = 12

/* -- FONTS AND TEXT -- */

// Use iosfonts.com, or change to "" for the system font.
const fontName = "Futura-Medium"

// Find colors on htmlcolorcodes.com
const fontColor = new Color("#ffffff")

const date = new Date()

const resetWidget = false

// Change the font sizes for each element.
const greetingSize = 17
const dateSize = 25
const dayOfWeekSize = 25
const eventTitleSize = 14
const eventTimeSize = 10
const noEventMessageSize = 14
const shawnTextSize = 29

const files = FileManager.local()
const path = files.joinPath(files.documentsDirectory(), Script.name() + ".jpg")

// If we're in the widget or testing, build the widget.
if (config.runsInWidget || (testMode && files.fileExists(path) && !resetWidget)) {
  const widget = new ListWidget()
  if (files.fileExists(path)) widget.backgroundImage = files.readImage(path)

  if (verticalAlignment == "middle" || verticalAlignment == "bottom") {
    widget.addSpacer()
  }

  // Format the greeting if we need it.
  if (showGreeting) {
    let greetingText = makeGreeting()
    let greeting = widget.addText(greetingText)
    formatText(greeting, greetingSize)
    widget.addSpacer(elementSpacing)
  }

  // Format the date info.
  let df = new DateFormatter()
  if (dateDisplay.toLowerCase() == "ios") {
    df.dateFormat = "EEEE"
    let dayOfWeek = widget.addText(df.string(date).toUpperCase())
    let dateNumber = widget.addText(date.getDate().toString())

    formatText(dayOfWeek, dayOfWeekSize)
    formatText(dateNumber, dateSize)
  } else {
    df.dateFormat = dateDisplay
    var dateText = widget.addText(df.string(date))
    formatText(dateText, dateSize)
  }
  
  var option = {month:'long', day:'numeric'}
  let shawn = widget.addText(new Date().toLocaleDateString("en-US", option).toString())
  formatText(shawn, shawnTextSize)

  // Add events if we're supposed to.
  if (showEvents) {
    // Your existing event display code here
    // [Previous event handling code remains unchanged]
  }

  if (verticalAlignment == "top" || verticalAlignment == "middle") {
    widget.addSpacer()
  }

  Script.setWidget(widget)
  if (testMode) {
    let widgetSizeFormat = widgetPreview.toLowerCase()
    if (widgetSizeFormat == "small")  { widget.presentSmall()  }
    if (widgetSizeFormat == "medium") { widget.presentMedium() }
    if (widgetSizeFormat == "large")  { widget.presentLarge()  }
  }
  Script.complete()

} else {
  // Background setup code
  let message = "Before you start, edit your home screen (wiggle mode). Scroll to the empty page on the far right and take a screenshot."
  const shouldExit = await generateAlert(message, ["Continue", "Exit to Take Screenshot"])
  if (shouldExit.index) return
  
  let img = await Photos.fromLibrary()
  const height = img.size.height
  let phone = phoneSizes(height)
  if (!phone) {
    message = "It looks like you selected an image that isn't an iPhone screenshot, or your iPhone is not supported. Try again with a different image."
    return await generateAlert(message, ["OK"])
  }
  
  if (phone.text) {
    message = "What size are your home screen icons?"
    const textOptions = [{key: "text", value: "Small (has labels)"}, {key: "notext", value: "Large (no labels)"}]
    const textResponse = await generateAlert(message, textOptions)
    phone = phone[textResponse.key]
  }
  
  message = "What size of widget are you creating?"
  const sizes = {small: "Small", medium: "Medium", large: "Large"}
  const sizeOptions = [sizes.small, sizes.medium, sizes.large]
  const size = (await generateAlert(message, sizeOptions)).value
  
  message = "What position will it be in?"
  message += (height == 1136 ? " (Note that your device only supports two rows of widgets, so the middle and bottom options are the same.)" : "")
  
  let positions
  if (size == sizes.small) {
    positions = ["Top left","Top right","Middle left","Middle right","Bottom left","Bottom right"]
  } else if (size == sizes.medium) {
    positions = ["Top","Middle","Bottom"]
  } else if (size == sizes.large) {
    positions = [{key: "top", value: "Top"}, {key: "middle", value: "Bottom"}]
  }
  const position = (await generateAlert(message, positions)).key

  const crop = { 
    w: (size == sizes.small ? phone.small : phone.medium),
    h: (size == sizes.large ? phone.large : phone.small),
    x: (size == sizes.small ? phone[position.split(" ")[1]] : phone.left),
    y: phone[position.toLowerCase().split(" ")[0]]
  }
  
  const draw = new DrawContext()
  draw.size = new Size(crop.w, crop.h)
  draw.drawImageAtPoint(img, new Point(-crop.x, -crop.y))  
  img = draw.getImage()
  
  message = "Your widget background is ready. Would you like to use it as this script's background, or export the image?"
  const exports = {script: "Use for this script", photos: "Export to Photos", files: "Export to Files"}
  const exportOptions = [exports.script, exports.photos, exports.files]
  const exportValue = (await generateAlert(message, exportOptions)).value
  
  if (exportValue == exports.script) {
    files.writeImage(path, img)
  } else if (exportValue == exports.photos) {
    Photos.save(img)
  } else if (exportValue == exports.files) {
    await DocumentPicker.exportImage(img)
  }
}

// Helper functions
async function generateAlert(message, options) {
  const alert = new Alert()
  alert.message = message
  
  const isObject = options[0].value
  for (const option of options) {
    alert.addAction(isObject ? option.value : option)
  }
  
  const index = await alert.presentAlert()
  return { 
    index: index, 
    value: isObject ? options[index].value : options[index],
    key: isObject ? options[index].key : options[index]
  }
}

function phoneSizes(inputHeight) {
  return {
    // 16 Pro Max
    "2868": {
      text: {
        small: 510,
        medium: 1092,
        large: 1146,
        left: 114,
        right: 696,
        top: 276,
        middle: 912,
        bottom: 1548
      },
      notext: {
        small: 530,
        medium: 1138,
        large: 1136,
        left: 91,
        right: 699,
        top: 276,
        middle: 882,
        bottom: 1488
      } 
    },
    
    // 16 Plus, 15 Plus, 15 Pro Max, 14 Pro Max
    "2796": {
      text: {
        small: 510,
        medium: 1092,
        large: 1146,
        left: 98,
        right: 681,
        top: 252,
        middle: 888,
        bottom: 1524
      },
      notext: {
        small: 530,
        medium: 1139,
        large: 1136,
        left: 75,
        right: 684,
        top: 252,
        middle: 858,
        bottom: 1464
      }
    },
    
    // 16 Pro
    "2622": {
      text: {
        small: 486,
        medium: 1032,
        large: 1098,
        left: 87,
        right: 633,
        top: 261,
        middle: 872,
        bottom: 1485
      },
      notext: {
        small: 495,
        medium: 1037,
        large: 1035,
        left: 84,
        right: 626,
        top: 270,
        middle: 810,
        bottom: 1350
      } 
    },

    // 16, 15, 15 Pro, 14 Pro
    "2556": {
      text: {
        small: 474,
        medium: 1017,
        large: 1062,
        left: 81,
        right: 624,
        top: 240,
        middle: 828,
        bottom: 1416
      },
      notext: {
        small: 495,
        medium: 1047,
        large: 1047,
        left: 66,
        right: 618,
        top: 243,
        middle: 795,
        bottom: 1347
      }
    }
  }[inputHeight]
}

// Your existing helper functions
function makeGreeting() {
  let greeting = "Good "
  if (date.getHours() < 4) {
    greeting = greeting + "night."
  } else if (date.getHours() < 12) {
    greeting = greeting + "morning."
  } else if (date.getHours() < 17) {
    greeting = greeting + "afternoon."
  } else if (date.getHours() < 20) {
    greeting = greeting + "evening."
  } else {
    greeting = greeting + "night."
  }
  return greeting
}

function shouldShowEvent(event) {
  if (event.title.startsWith("Canceled:")) {
    return false
  }
  if (event.isAllDay) {
    return showAllDay
  }
  return (event.startDate.getTime() > date.getTime())
}

function provideFont(fontName, fontSize) {
  if (fontName == "" || fontName == null) {
    return Font.regularSystemFont(fontSize)
  } else {
    return new Font(fontName, fontSize)
  }
}

function displayEvent(widget, event) {
  widget.addSpacer(elementSpacing)
  let title = widget.addText(event.title)
  formatText(title, eventTitleSize)
  if (event.isAllDay) { return }
  widget.addSpacer(7)
  let time = widget.addText(formatTime(event.startDate))
  formatText(time, eventTimeSize)
}

function formatTime(date) {
  let df = new DateFormatter()
  df.useNoDateStyle()
  df.useShortTimeStyle()
  return df.string(date)
}

function formatText(textItem, fontSize) {
  textItem.font = provideFont(fontName, fontSize)
  textItem.textColor = fontColor
  if (horizontalAlignment == "right") {
    textItem.rightAlignText()
  } else if (horizontalAlignment == "center") {
    textItem.centerAlignText()
  } else {
    textItem.leftAlignText()
  }
}

function sameDay(d1, d2) {
  return d1.getFullYear() === d2.getFullYear() &&
    d1.getMonth() === d2.getMonth() &&
    d1.getDate() === d2.getDate()
}