const { div, h2, h3, h4, p, section, button, form, a, span, br, textarea, input, label, select, option, table, tr, td, ul, li } = require("../server/node_modules/hyperaxe")
const { template, i18n, userLink, renderStateChip, renderLifespanChip, renderSpreadButton } = require("./main_views")
const { renderEncryptedChip } = require("./clearnet_view")
const moment = require("../server/node_modules/moment")
const { config } = require("../server/SSB_server.js")

const userId = config.keys.id

const renderNoteText = (text) => {
  if (!text) return []
  const urlRegex = /(https?:\/\/[^\s]+)/g
  const result = []
  let last = 0
  text.replace(urlRegex, (match, _g, offset) => {
    if (offset > last) result.push(text.slice(last, offset))
    result.push(a({ href: match, target: "_blank" }, match))
    last = offset + match.length
  })
  if (last < text.length) result.push(text.slice(last))
  return result
}

const renderCalendarFavoriteToggle = (cal, returnTo) =>
  form(
    { method: "POST", action: cal.isFavorite ? `/calendars/favorites/remove/${encodeURIComponent(cal.rootId)}` : `/calendars/favorites/add/${encodeURIComponent(cal.rootId)}` },
    returnTo ? input({ type: "hidden", name: "returnTo", value: returnTo }) : null,
    button({ type: "submit", class: "tribe-action-btn" }, cal.isFavorite ? (i18n.calendarRemoveFavorite || "Remove Favorite") : (i18n.calendarAddFavorite || "Add Favorite"))
  )

const renderModeButtons = (currentFilter) =>
  div({ class: "tribe-mode-buttons" },
    ["all", "mine", "recent", "favorites", "open", "closed"].map(f =>
      form({ method: "GET", action: "/calendars" },
        input({ type: "hidden", name: "filter", value: f }),
        button({ type: "submit", class: currentFilter === f ? "filter-btn active" : "filter-btn" },
          i18n[`calendarFilter${f.charAt(0).toUpperCase() + f.slice(1)}`] || f.toUpperCase())
      )
    ),
    form({ method: "GET", action: "/calendars" },
      input({ type: "hidden", name: "filter", value: "create" }),
      button({ type: "submit", class: "create-button" }, i18n.calendarCreate || "Create Calendar")
    )
  )

const renderStatus = (cal) => {
  if (cal.isClosed) return span({ class: "pad-status-closed" }, i18n.calendarStatusClosed || "CLOSED")
  return span({ class: "pad-status-open" }, i18n.calendarStatusOpen || "OPEN")
}

const renderCalendarStatusChip = (cal) => {
  const isClosed = !!cal.isClosed
  const variant = isClosed ? "closed" : "mutuals"
  const icon = isClosed ? "\u2717" : "\u2713"
  const label = isClosed ? (i18n.calendarStatusClosed || "CLOSED") : (i18n.calendarStatusOpen || "OPEN")
  return renderStateChip(variant, icon, label)
}

const renderCalendarCard = (cal, spreadInfo) => {
  const href = `/calendars/${encodeURIComponent(cal.rootId)}`
  const chips = [
    renderCalendarStatusChip(cal),
    renderEncryptedChip(i18n),
    renderLifespanChip(cal.lifetime, i18n)
  ].filter(Boolean)
  return div({ class: "tribe-card" },
    div({ class: "tribe-card-body" },
      div({ class: "shop-title-row" },
        h2({ class: "tribe-card-title" }, a({ href }, cal.title || "\u2014"))
      ),
      chips.length ? div({ class: "card-chips-row" }, ...chips) : null,
      cal.deadline
        ? p({ class: "job-meta-line" }, `${i18n.calendarDeadlineLabel || "Deadline"}: ${moment(cal.deadline).format("YYYY-MM-DD HH:mm")}`)
        : null,
      div({ class: "tribe-card-members" },
        span({ class: "tribe-members-count calendar-participants-count" }, `${i18n.calendarParticipantsLabel || "Participants"}: ${cal.participants.length}`)
      ),
      div({ class: "card-spread-centered" }, renderSpreadButton(cal.rootId, spreadInfo)),
      div({ class: "card-visit-btn-centered" },
        a({ href, class: "filter-btn" }, i18n.calendarVisitCalendar || "Visit Calendar")
      )
    )
  )
}

const renderIntervalBlock = () =>
  div({ class: "calendar-interval-block" },
    span({ class: "calendar-interval-label" }, i18n.calendarIntervalLabel || "Interval"),
    div({ class: "calendar-interval-row" },
      input({ type: "hidden", name: "intervalWeekly", value: "0" }),
      label({ class: "calendar-interval-option" },
        input({ type: "checkbox", name: "intervalWeekly", value: "1" }),
        " ", i18n.calendarIntervalWeekly || "Weekly"
      ),
      input({ type: "hidden", name: "intervalMonthly", value: "0" }),
      label({ class: "calendar-interval-option" },
        input({ type: "checkbox", name: "intervalMonthly", value: "1" }),
        " ", i18n.calendarIntervalMonthly || "Monthly"
      ),
      input({ type: "hidden", name: "intervalYearly", value: "0" }),
      label({ class: "calendar-interval-option" },
        input({ type: "checkbox", name: "intervalYearly", value: "1" }),
        " ", i18n.calendarIntervalYearly || "Yearly"
      )
    ),
    span({ class: "calendar-interval-label calendar-interval-until" }, i18n.calendarIntervalUntil || "Until"),
    input({ type: "datetime-local", name: "intervalDeadline" }),
    br()
  )

const renderCreateForm = (calendarToEdit, params) => {
  const isEdit = !!calendarToEdit
  const tribeId = (params && params.tribeId) || ""
  const now = moment().add(1, "minute").format("YYYY-MM-DDTHH:mm")
  const action = isEdit ? `/calendars/update/${encodeURIComponent(calendarToEdit.rootId)}` : "/calendars/create"
  const sectionTitle = isEdit ? (i18n.calendarUpdateSectionTitle || "Update Calendar") : (i18n.calendarCreateSectionTitle || "Create New Calendar")
  return div({ class: "div-center audio-form" },
    h2(sectionTitle),
    form({ method: "POST", action },
      tribeId ? input({ type: "hidden", name: "tribeId", value: tribeId }) : null,
      span(i18n.calendarTitleLabel || "Title"), br(),
      input({ type: "text", name: "title", required: true, placeholder: i18n.calendarTitlePlaceholder || "Calendar title...", value: calendarToEdit ? calendarToEdit.title : "" }),
      br(), br(),
      span(i18n.calendarStatusLabel || "Status"), br(),
      select({ name: "status", required: true },
        option({ value: "OPEN", ...((!calendarToEdit || calendarToEdit.status === "OPEN") ? { selected: true } : {}) }, i18n.calendarStatusOpen || "OPEN"),
        option({ value: "CLOSED", ...((calendarToEdit && calendarToEdit.status === "CLOSED") ? { selected: true } : {}) }, i18n.calendarStatusClosed || "CLOSED")
      ),
      br(), br(),
      span(i18n.calendarDeadlineLabel || "Deadline"), br(),
      input({ type: "datetime-local", name: "deadline", required: true, min: now, value: calendarToEdit && calendarToEdit.deadline ? moment(calendarToEdit.deadline).format("YYYY-MM-DDTHH:mm") : "" }),
      br(), br(),
      span(i18n.calendarTagsLabel || "Tags"), br(),
      input({ type: "text", name: "tags", placeholder: i18n.calendarTagsPlaceholder || "tag1, tag2...", value: calendarToEdit && Array.isArray(calendarToEdit.tags) ? calendarToEdit.tags.join(", ") : "" }),
      br(), br(),
      !isEdit
        ? [
            span(i18n.calendarFirstDateLabel || "Date"), br(),
            input({ type: "datetime-local", name: "firstDate", required: true, min: now }),
            br(), br(),
            span(i18n.calendarFormDescription || "Description"), br(),
            input({ type: "text", name: "firstDateLabel", placeholder: i18n.calendarDatePlaceholder || "Describe this date..." }),
            br(), br(),
            renderIntervalBlock(),
            span(i18n.calendarFirstNoteLabel || "Notes"), br(),
            textarea({ name: "firstNote", rows: "3", placeholder: i18n.calendarNotePlaceholder || "Add a note..." }),
            br(), br()
          ]
        : null,
      button({ type: "submit", class: "create-button" }, isEdit ? (i18n.calendarUpdate || "Update") : (i18n.calendarCreate || "Create Calendar"))
    )
  )
}

const renderMonthGrid = (year, month, datesMap, calendarId) => {
  const DAY_NAMES = ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"]
  const firstDay = new Date(year, month, 1)
  const daysInMonth = new Date(year, month + 1, 0).getDate()
  const startPad = (firstDay.getDay() + 6) % 7
  const monthStr = `${year}-${String(month + 1).padStart(2, "0")}`

  const headerCells = DAY_NAMES.map(d => div({ class: "calendar-day-header" }, d))
  const cells = []

  for (let i = 0; i < startPad; i++) cells.push(div({ class: "calendar-day calendar-day-empty" }, " "))

  for (let day = 1; day <= daysInMonth; day++) {
    const dateStr = `${year}-${String(month + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`
    const marked = datesMap && datesMap[dateStr] && datesMap[dateStr].length > 0
    if (marked) {
      cells.push(
        div({ class: "calendar-day calendar-day-marked" },
          a({ href: `/calendars/${encodeURIComponent(calendarId)}?month=${monthStr}&day=${dateStr}` }, String(day))
        )
      )
    } else {
      cells.push(div({ class: "calendar-day" }, String(day)))
    }
  }

  return div({ class: "calendar-grid" }, ...headerCells, ...cells)
}

exports.renderCalendarInvitePage = (code) => {
  const pageContent = div({ class: "invite-page" },
    h2(i18n.tribeInviteCodeText, code),
    form({ method: "GET", action: "/calendars" },
      input({ type: "hidden", name: "filter", value: "all" }),
      button({ type: "submit", class: "filter-btn" }, i18n.walletBack)
    )
  )
  return template(i18n.calendarGenerateInvite || "Invite", section(pageContent))
}

exports.calendarsView = async (calendars, filter, calendarToEdit, params) => {
  const q = (params && params.q) || ""
  const showForm = filter === "create" || filter === "edit" || !!calendarToEdit
  const headerMap = {
    all: i18n.calendarAllSectionTitle || "Calendars",
    mine: i18n.calendarMineSectionTitle || "Your Calendars",
    recent: i18n.calendarRecentSectionTitle || "Recent Calendars",
    favorites: i18n.calendarFavoritesSectionTitle || "Favorites",
    open: i18n.calendarOpenSectionTitle || "Open Calendars",
    closed: i18n.calendarClosedSectionTitle || "Closed Calendars"
  }
  const headerText = headerMap[filter] || headerMap.all

  return template(
    i18n.calendarsTitle || "Calendars",
    section(
      div({ class: "tags-header" },
        h2(headerText),
        p(i18n.calendarsDescription || "Discover and manage calendars.")
      ),
      renderModeButtons(filter),
      q
        ? div({ class: "filters" },
            form({ method: "GET", action: "/calendars" },
              input({ type: "text", name: "q", value: q, placeholder: i18n.calendarSearchPlaceholder || "Search calendars..." }),
              button({ type: "submit", class: "filter-btn" }, i18n.searchButton || "Search")
            )
          )
        : null
    ),
    section(
      showForm
        ? renderCreateForm(calendarToEdit, params)
        : (calendars.length > 0
            ? div({ class: "tribe-grid" }, ...calendars.map(c => renderCalendarCard(c, params && params.spreadMap && params.spreadMap.get(c.rootId))))
            : p({ class: "no-content" }, i18n.calendarsNoItems || "No calendars found."))
    )
  )
}

exports.singleCalendarView = async (calendar, dates, notesByDate, params) => {
  const { month: monthStr, day: selectedDay } = params || {}
  const isAuthor = calendar.author === userId
  const isParticipant = calendar.participants.includes(userId)
  const calClosed = calendar.isClosed
  const shareUrl = `/calendars/${encodeURIComponent(calendar.rootId)}`

  const now = moment()
  const currentMonth = monthStr ? moment(monthStr, "YYYY-MM") : now.clone().startOf("month")
  const prevMonth = currentMonth.clone().subtract(1, "month").format("YYYY-MM")
  const nextMonth = currentMonth.clone().add(1, "month").format("YYYY-MM")
  const year = currentMonth.year()
  const month = currentMonth.month()

  const datesMap = {}
  for (const d of dates) {
    const dayKey = moment(d.date).format("YYYY-MM-DD")
    if (!datesMap[dayKey]) datesMap[dayKey] = []
    datesMap[dayKey].push(d)
  }

  const tags = Array.isArray(calendar.tags) && calendar.tags.length > 0
    ? div({ class: "tribe-side-tags" }, ...calendar.tags.map(t => a({ href: `/search?query=%23${encodeURIComponent(t)}` }, `#${t} `)))
    : null

  const detailChips = [
    renderCalendarStatusChip(calendar),
    renderEncryptedChip(i18n),
    renderLifespanChip(calendar.lifetime, i18n)
  ].filter(Boolean)
  const calSide = div({ class: "tribe-side" },
    div({ class: "shop-title-row" },
      h2({ class: "tribe-card-title" }, calendar.title || "\u2014")
    ),
    detailChips.length ? div({ class: "card-chips-row" }, ...detailChips) : null,
    div({ class: "card-spread-centered" }, renderSpreadButton(calendar.rootId, params && params.spreads)),
    div({ class: "shop-share" },
      span({ class: "tribe-info-label" }, i18n.calendarsShareUrl || "Share URL"),
      input({ type: "text", readonly: true, value: shareUrl, class: "shop-share-input" })
    ),
    table({ class: "tribe-info-table" },
      tr(td({ class: "tribe-info-label" }, i18n.calendarCreated || "Created"), td({ class: "tribe-info-value", colspan: "3" }, moment(calendar.createdAt).format("YYYY-MM-DD"))),
      tr(td({ class: "tribe-info-label" }, i18n.calendarStatusLabel || "Status"), td({ class: "tribe-info-value", colspan: "3" }, renderStatus(calendar))),
      tr(td({ class: "tribe-info-value", colspan: "4" }, userLink(calendar.author))),
      calendar.deadline ? tr(td({ class: "tribe-info-label" }, i18n.calendarDeadlineLabel || "Deadline"), td({ class: "tribe-info-value", colspan: "3" }, moment(calendar.deadline).format("YYYY-MM-DD HH:mm"))) : null
    ),
    div({ class: "tribe-side-actions" },
      renderCalendarFavoriteToggle(calendar, shareUrl),
      isAuthor
        ? form({ method: "GET", action: "/calendars" },
            input({ type: "hidden", name: "filter", value: "edit" }),
            input({ type: "hidden", name: "id", value: calendar.rootId }),
            button({ type: "submit", class: "tribe-action-btn" }, i18n.calendarUpdate || "Update")
          )
        : null,
      isAuthor && calendar.status !== "OPEN"
        ? form({ method: "POST", action: `/calendars/generate-invite/${encodeURIComponent(calendar.rootId)}` },
            button({ type: "submit", class: "tribe-action-btn" }, i18n.calendarGenerateInvite || "Generate invite")
          )
        : null,
      isAuthor
        ? form({ method: "POST", action: `/calendars/delete/${encodeURIComponent(calendar.rootId)}` },
            button({ type: "submit", class: "tribe-action-btn danger-btn" }, i18n.calendarDelete || "Delete")
          )
        : null,
      !isAuthor
        ? a({ href: `/pm?to=${encodeURIComponent(calendar.author)}`, class: "tribe-action-btn" }, "PM")
        : null,
      !isAuthor && !isParticipant && calendar.status === "OPEN"
        ? form({ method: "POST", action: `/calendars/join/${encodeURIComponent(calendar.rootId)}` },
            button({ type: "submit", class: "create-button" }, i18n.calendarJoin || "Join Calendar")
          )
        : null,
      !isAuthor && !isParticipant && calendar.status !== "OPEN"
        ? form({ method: "POST", action: "/calendars/join-code" },
            input({ type: "text", name: "code", placeholder: i18n.calendarInviteCodePlaceholder || "Enter invite code..." }),
            button({ type: "submit", class: "filter-btn" }, i18n.calendarValidateInvite || "Validate code")
          )
        : null,
      !isAuthor && isParticipant
        ? form({ method: "POST", action: `/calendars/leave/${encodeURIComponent(calendar.rootId)}` },
            button({ type: "submit", class: "tribe-action-btn danger-btn" }, i18n.calendarLeave || "Leave Calendar")
          )
        : null
    ),
    tags,
    div({ class: "tribe-card-members" },
      span({ class: "tribe-members-count calendar-participants-count" }, `${i18n.calendarParticipantsLabel || "Participants"}: ${calendar.participants.length}`)
    )
  )

  const minDate = now.add(1, "minute").format("YYYY-MM-DDTHH:mm")
  const canAddDate = !calClosed && (calendar.status === "OPEN" || isAuthor)

  const unifiedForm = canAddDate
    ? div({ class: "div-center audio-form" },
        h4(i18n.calendarAddEntry || "Add Entry"),
        form({ method: "POST", action: `/calendars/add-date/${encodeURIComponent(calendar.rootId)}` },
          span(i18n.calendarDateLabel || "Date"), br(),
          input({ type: "datetime-local", name: "date", required: true, min: minDate }),
          br(), br(),
          span(i18n.calendarFormDescription || "Description"), br(),
          input({ type: "text", name: "label", placeholder: i18n.calendarDatePlaceholder || "Describe this date..." }),
          br(), br(),
          renderIntervalBlock(),
          br(),
          isParticipant
            ? [
                span(i18n.calendarNoteLabel || "Note (optional)"), br(),
                textarea({ name: "text", rows: "3", placeholder: i18n.calendarNotePlaceholder || "Add a note..." }),
                br(), br()
              ]
            : null,
          button({ type: "submit", class: "create-button" }, i18n.calendarAddEntry || "Add Entry")
        )
      )
    : null

  const monthLabel = currentMonth.format("MMMM YYYY")
  const calNav = div({ class: "calendar-nav" },
    a({ href: `${shareUrl}?month=${prevMonth}`, class: "filter-btn" }, i18n.calendarMonthPrev || "\u2190 Prev"),
    span({ class: "tribe-info-label" }, monthLabel),
    a({ href: `${shareUrl}?month=${nextMonth}`, class: "filter-btn" }, i18n.calendarMonthNext || "Next \u2192")
  )

  const grid = renderMonthGrid(year, month, datesMap, calendar.rootId)

  const dayEntries = selectedDay
    ? dates.filter(d => moment(d.date).format("YYYY-MM-DD") === selectedDay)
    : []

  const dayNotesSection = selectedDay
    ? div({ class: "calendar-day-notes" },
        h4(`${selectedDay}${dayEntries.length > 0 && dayEntries[0].label ? " \u2014 " + dayEntries[0].label : ""}`),
        dayEntries.length === 0
          ? p({ class: "no-content" }, i18n.calendarNoDates || "No dates added yet.")
          : div(null, ...dayEntries.map(d => {
              const notes = (notesByDate && notesByDate[d.key]) ? notesByDate[d.key] : []
              return div({ class: "calendar-date-item" },
                (isAuthor || String(d.author) === String(userId))
                  ? form({ method: "POST", action: `/calendars/delete-date/${encodeURIComponent(d.key)}`, class: "calendar-date-delete" },
                      input({ type: "hidden", name: "calendarId", value: calendar.rootId }),
                      button({ type: "submit", class: "tribe-action-btn danger-btn" }, i18n.calendarDeleteDate || "Delete Date")
                    )
                  : null,
                div({ class: "calendar-date-item-header" },
                  `${moment(d.date).format("YYYY-MM-DD HH:mm")}${d.label ? " \u2014 " + d.label : ""}`
                ),
                (() => {
                  const visibleNotes = notes.filter(n => n.text && String(n.text).trim())
                  return visibleNotes.length === 0
                    ? p({ class: "no-content" }, i18n.calendarNoNotes || "No notes.")
                    : div(null, ...visibleNotes.map(n => {
                      const isSelf = String(n.author) === String(userId)
                      const dateStr = moment(n.createdAt).format("YYYY/MM/DD HH:mm")
                      const shortId = n.author ? "@" + n.author.slice(1, 9) + "\u2026" : "?"
                      return div({ class: (isSelf ? "chat-message chat-message-self" : "chat-message") + " calendar-note-card" },
                        isSelf
                          ? form({ method: "POST", action: `/calendars/delete-note/${encodeURIComponent(n.key)}`, class: "calendar-note-delete" },
                              input({ type: "hidden", name: "calendarId", value: calendar.rootId }),
                              button({ type: "submit", class: "tribe-action-btn danger-btn" }, i18n.calendarDeleteNote || "Delete")
                            )
                          : null,
                        div({ class: "chat-message-meta" },
                          span({ class: "chat-message-sender" },
                            userLink(n.author)
                          ),
                          span({ class: "chat-message-date" }, ` [ ${dateStr} ]`)
                        ),
                        span({ class: "chat-message-text" }, ...renderNoteText(n.text || ""))
                      )
                    }))
                })()
              )
            }))
      )
    : null

  const calMain = div({ class: "tribe-main" },
    calNav,
    grid,
    dayNotesSection,
    unifiedForm
  )

  return template(
    calendar.title || i18n.calendarsTitle || "Calendar",
    section(
      div({ class: "tags-header" },
        h2(i18n.calendarsTitle || "Calendars"),
        p(i18n.calendarsDescription || "Discover and manage calendars.")
      ),
      renderModeButtons("all")
    ),
    section(div({ class: "tribe-details" }, calSide, calMain))
  )
}
