#[Copyright 2025 ITwrx.
This file is part of Forget-Me-Not.
Forget-Me-Not is released under the GNU Affero General Public License 3.0.
See COPYING or <https://www.gnu.org/licenses/> for details.]#

import guildenstern/httpserver
import "../helpers/form", "../helpers/global", "../helpers/validation"
import "../models/reminder"

proc reminderCreatePostHandler*() =
  #try to save to DB.
  try:
    #attempt validation first.
    vInput("title", @["required", "string", "max:150"])
    vInput("message", @["required", "string", "max:255"])
    vInput("notify_via", @["required", "string", "max:5"])
    vInput("repeats", @["integer", "max:1"])
    vInput("repeat_freq", @["required_with:repeats", "string", "max:10"])
    vInput("weekly_on", @["required_when:repeat_freq:equals:week", "string", "max:10"])
    vInput("monthly_on_day", @["required_when:repeat_freq:equals:month:without:monthly_on_week", "integer", "max:31"])
    vInput("monthly_on_weekday", @["required_with:monthly_on_week", "string", "max:10"])
    vInput("monthly_on_week", @["required_when:repeat_freq:equals:month:without:monthly_on_day", "string", "max:4"])
    vInput("yearly_on_month", @["required_when:repeat_freq:equals:year:without:yearly_on_week", "string", "max:12"])
    vInput("yearly_on_day", @["required_with:yearly_on_month", "integer", "max:31"])
    vInput("yearly_on_week", @["required_when:repeat_freq:equals:year:without:yearly_on_month", "string", "max:4"])
    vInput("yearly_on_weekday", @["required_with:yearly_on_week", "string", "max:10"])
    vInput("yearly_on_month2", @["required_with:yearly_on_week", "string", "max:12"])
    vInput("send_date", @["required", "string", "max:10"])
    vInput("send_time_hr", @["required", "integer", "max:12"])
    vInput("send_time_min", @["required", "integer", "max:60"])
    vInput("send_time_am_pm", @["required", "string", "max:2"])
    #create formResult and redirect on validation errors.
    if formErrors.len > 0:
      addFormOldInput("title", formInput("title"))
      addFormOldInput("message", formInput("message"))
      addFormOldInput("notify_via", formInput("notify_via"))
      addFormOldInput("repeats", formInput("repeats"))
      addFormOldInput("repeat_freq", formInput("repeat_freq"))
      addFormOldInput("weekly_on", formInput("weekly_on"))
      addFormOldInput("monthly_on_day", formInput("monthly_on_day"))
      addFormOldInput("monthly_on_weekday", formInput("monthly_on_weekday"))
      addFormOldInput("monthly_on_week", formInput("monthly_on_week"))
      addFormOldInput("yearly_on_month", formInput("yearly_on_month"))
      addFormOldInput("yearly_on_day", formInput("yearly_on_day"))
      addFormOldInput("yearly_on_week", formInput("yearly_on_week"))
      addFormOldInput("yearly_on_weekday", formInput("yearly_on_weekday"))
      addFormOldInput("yearly_on_month2", formInput("yearly_on_month2"))
      addFormOldInput("send_date", formInput("send_date"))
      addFormOldInput("send_time_hr", formInput("send_time_hr"))
      addFormOldInput("send_time_min", formInput("send_time_min"))
      addFormOldInput("send_time_am_pm", formInput("send_time_am_pm"))
      discard assignErrorFR(formErrors, formOldInputs)
      setFR()
      reply(Http303, [locationBack()])
    #validation passed. Save posted data to db.
    else:
      var reminder: Reminder
      reminder.title = formInput("title")
      reminder.message = formInput("message")
      reminder.notifyVia = formInput("notify_via")
      reminder.repeats = formInputInt("repeats")
      reminder.repeatFreq = formInput("repeat_freq")
      reminder.weeklyOn = formInput("weekly_on")
      reminder.monthlyOnDay = formInputInt("monthly_on_day")
      reminder.monthlyOnWeekday = formInput("monthly_on_weekday")
      reminder.monthlyOnWeek = formInput("monthly_on_week")
      reminder.yearlyOnMonth = formInput("yearly_on_month")
      reminder.yearlyOnDay = formInputInt("yearly_on_day")
      reminder.yearlyOnWeek = formInput("yearly_on_week")
      reminder.yearlyOnWeekday = formInput("yearly_on_weekday")
      reminder.yearlyOnMonth2 = formInput("yearly_on_month2")
      reminder.sendDate = formInput("send_date")
      reminder.sendTimeHr = formInputInt("send_time_hr")
      reminder.sendTimeMin = formInputInt("send_time_min")
      reminder.sendTimeAmPm = formInput("send_time_am_pm")
      let reminderId = createReminder(reminder)
      clearAllReminders()
      discard assignCEEditSuccessFR()
      setFR()
      reply(Http303, [location("/")])
  except CatchableError as e:
    echo e.msg
    discard assignGeneralErrorFR(e.msg)
    setFR()
    reply(Http303, [location("/500")])

proc reminderUpdatePostHandler*() =
  try:
    #var origin = http.headers.getOrDefault("origin")
    #attempt validation first.
    vInput("title", @["required", "string", "max:150"])
    vInput("message", @["required", "string", "max:255"])
    vInput("notify_via", @["required", "string", "max:5"])
    vInput("repeats", @["integer", "max:1"])
    vInput("repeat_freq", @["required_with:repeats", "string", "max:10"])
    vInput("weekly_on", @["required_when:repeat_freq:equals:week", "string", "max:10"])
    vInput("monthly_on_day", @["required_when:repeat_freq:equals:month:without:monthly_on_week", "must_unset_with:monthly_on_week", "must_unset_with:monthly_on_weekday", "integer", "max:31"])
    vInput("monthly_on_weekday", @["required_with:monthly_on_week", "must_unset_with:monthly_on_day", "string", "max:10"])
    vInput("monthly_on_week", @["required_when:repeat_freq:equals:month:without:monthly_on_day", "must_unset_with:monthly_on_day", "string", "max:4"])
    vInput("yearly_on_month", @["required_when:repeat_freq:equals:year:without:yearly_on_week", "must_unset_with:yearly_on_week", "must_unset_with:yearly_on_weekday", "must_unset_with:yearly_on_month2", "string", "max:12"])
    vInput("yearly_on_day", @["required_with:yearly_on_month", "must_unset_with:yearly_on_week", "must_unset_with:yearly_on_weekday", "must_unset_with:yearly_on_month2", "integer", "max:31"])
    vInput("yearly_on_week", @["required_when:repeat_freq:equals:year:without:yearly_on_month", "must_unset_with:yearly_on_month", "must_unset_with:yearly_on_day", "string", "max:4"])
    vInput("yearly_on_weekday", @["required_with:yearly_on_week", "must_unset_with:yearly_on_month", "must_unset_with:yearly_on_day", "string", "max:10"])
    vInput("yearly_on_month2", @["required_with:yearly_on_week", "must_unset_with:yearly_on_month", "must_unset_with:yearly_on_day", "string", "max:12"])
    vInput("send_date", @["required", "string", "max:10", "future_datetime"])
    vInput("send_time_hr", @["required", "integer", "max:12"])
    vInput("send_time_min", @["required", "integer", "max:60"])
    vInput("send_time_am_pm", @["required", "string", "max:2"])
    #create formResult and redirect on validation errors.
    if formErrors.len > 0:
      #since validation failed we better keep add the old inputs.
      addFormOldInput("title", formInput("title"))
      addFormOldInput("message", formInput("message"))
      addFormOldInput("notify_via", formInput("notify_via"))
      addFormOldInput("repeats", formInput("repeats"))
      addFormOldInput("repeat_freq", formInput("repeat_freq"))
      addFormOldInput("weekly_on", formInput("weekly_on"))
      addFormOldInput("monthly_on_day", formInput("monthly_on_day"))
      addFormOldInput("monthly_on_weekday", formInput("monthly_on_weekday"))
      addFormOldInput("monthly_on_week", formInput("monthly_on_week"))
      addFormOldInput("yearly_on_month", formInput("yearly_on_month"))
      addFormOldInput("yearly_on_day", formInput("yearly_on_day"))
      addFormOldInput("yearly_on_week", formInput("yearly_on_week"))
      addFormOldInput("yearly_on_weekday", formInput("yearly_on_weekday"))
      addFormOldInput("yearly_on_month2", formInput("yearly_on_month2"))
      addFormOldInput("send_date", formInput("send_date"))
      addFormOldInput("send_time_hr", formInput("send_time_hr"))
      addFormOldInput("send_time_min", formInput("send_time_min"))
      addFormOldInput("send_time_am_pm", formInput("send_time_am_pm"))
      discard assignErrorFR(formErrors, formOldInputs)
      setFR()
      reply(Http303, [locationBack()])
    #validation passed. Save posted data to db and redirect back with success message.
    else:
      var reminder: Reminder
      reminder.id = formInputInt("reminder_id")
      reminder.title = formInput("title")
      reminder.message = formInput("message")
      reminder.notifyVia = formInput("notify_via")
      reminder.repeats = formInputInt("repeats")
      reminder.repeatFreq = formInput("repeat_freq")
      reminder.weeklyOn = formInput("weekly_on")
      reminder.monthlyOnDay = formInputInt("monthly_on_day")
      reminder.monthlyOnWeekday = formInput("monthly_on_weekday")
      reminder.monthlyOnWeek = formInput("monthly_on_week")
      reminder.yearlyOnMonth = formInput("yearly_on_month")
      reminder.yearlyOnDay = formInputInt("yearly_on_day")
      reminder.yearlyOnWeek = formInput("yearly_on_week")
      reminder.yearlyOnWeekday = formInput("yearly_on_weekday")
      reminder.yearlyOnMonth2 = formInput("yearly_on_month2")
      reminder.sendDate = formInput("send_date")
      reminder.sendTimeHr = formInputInt("send_time_hr")
      reminder.sendTimeMin = formInputInt("send_time_min")
      reminder.sendTimeAmPm = formInput("send_time_am_pm")
      updateReminder(reminder)
      clearAllReminders()
      discard assignCEEditSuccessFR()
      setFR()
      reply(Http303, [location("/")])
  except CatchableError as e:
    echo e.msg
    discard assignGeneralErrorFR(e.msg)
    setFR()
    reply(Http303, [location("/500")])

proc reminderDeletePostHandler*() =
  try:
    vInput("reminder_id", @["integer", "max:200000"])
    #create formResult and redirect on validation errors.
    if formErrors.len > 0:
      #since validation failed we better add the old inputs.
      discard assignErrorFR(formErrors, formOldInputs)
      setFR()
      reply(Http303, [locationBack()])
    #validation passed. Save posted data to db and redirect back with success message.
    else:
      let reminderId = formInputInt("reminder_id")
      deleteReminder(reminderId)
      clearAllReminders()
      discard assignCEDeleteSuccessFR()
      setFR()
      reply(Http303, [location("/")])
  except CatchableError as e:
    echo e.msg
    discard assignGeneralErrorFR(e.msg)
    setFR()
    reply(Http303, [location("/500")])