// Timeline controller for handling timezone conversion and animations
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = ["row", "time", "bar", "timestamp", "date"]
  static values = {
    mode: { type: String, default: "timeline" } // "timeline", "events", or "individual"
  }

  connect() {
    if (this.modeValue === "timeline") {
      this.maxTotal = this.calculateMaxTotal()
      this.updateTimeline()
    } else if (this.modeValue === "events") {
      this.updateEventsTimes()
    } else {
      this.updateIndividualTimes()
    }
  }

  calculateMaxTotal() {
    const totals = this.rowTargets.map(row => parseInt(row.dataset.total))
    return Math.max(...totals, 1)
  }

  updateTimeline() {
    this.rowTargets.forEach((row, index) => {
      this.updateRow(row, index)
    })
  }

  updateRow(row, index) {
    const timeIso = row.dataset.timeIso
    const total = parseInt(row.dataset.total)
    const timeElement = this.timeTargets.find(target => target.closest('[data-timeline-target="row"]') === row)
    const barElement = this.barTargets.find(target => target.closest('[data-timeline-target="row"]') === row)

    // Convert ISO time to local time
    const date = new Date(timeIso)
    const localTime = date.toLocaleTimeString(undefined, {
      hour: '2-digit',
      minute: '2-digit',
      hour12: false
    })

    timeElement.textContent = localTime
    timeElement.title = date.toLocaleString(undefined, {
      weekday: 'short',
      year: 'numeric',
      month: 'short',
      day: 'numeric',
      hour: '2-digit',
      minute: '2-digit',
      timeZoneName: 'short'
    })

    // Animate the bar width with a slight delay for each row
    const barWidth = Math.max((total / this.maxTotal) * 100, 5)
    setTimeout(() => {
      barElement.style.width = `${barWidth}%`
    }, 100 + (index * 50))
  }

  updateEventsTimes() {
    this.timestampTargets.forEach(element => {
      const iso = element.dataset.iso
      if (iso) {
        this.convertToLocalTime(element, iso, "time")
      }
    })

    this.dateTargets.forEach(element => {
      const iso = element.dataset.iso
      if (iso) {
        this.convertToLocalTime(element, iso, "date")
      }
    })
  }

  updateIndividualTimes() {
    const iso = this.element.dataset.iso
    if (iso) {
      this.convertToLocalTime(this.element, iso, this.element.dataset.format || "both")
    }
  }

  convertToLocalTime(element, isoString, format) {
    const date = new Date(isoString)

    switch (format) {
      case "time":
        element.textContent = date.toLocaleTimeString(undefined, {
          hour: '2-digit',
          minute: '2-digit',
          second: '2-digit',
          hour12: false
        })
        element.title = date.toLocaleString(undefined, {
          weekday: 'short',
          year: 'numeric',
          month: 'short',
          day: 'numeric',
          hour: '2-digit',
          minute: '2-digit',
          second: '2-digit',
          timeZoneName: 'short'
        })
        break
      case "date":
        element.textContent = date.toLocaleDateString(undefined, {
          year: 'numeric',
          month: '2-digit',
          day: '2-digit'
        })
        element.title = date.toLocaleString(undefined, {
          weekday: 'short',
          year: 'numeric',
          month: 'short',
          day: 'numeric',
          hour: '2-digit',
          minute: '2-digit',
          second: '2-digit',
          timeZoneName: 'short'
        })
        break
      case "both":
        element.textContent = date.toLocaleString(undefined, {
          year: 'numeric',
          month: '2-digit',
          day: '2-digit',
          hour: '2-digit',
          minute: '2-digit',
          second: '2-digit',
          hour12: false
        })
        element.title = date.toLocaleString(undefined, {
          weekday: 'short',
          year: 'numeric',
          month: 'short',
          day: 'numeric',
          hour: '2-digit',
          minute: '2-digit',
          second: '2-digit',
          timeZoneName: 'short'
        })
        break
    }
  }
}