module VideoDataAnalyzer
  def get_top_substances(limit = 10)
    substance_counts = Hash.new(0)
    @data.each { |entry| substance_counts[entry[:substance]] += 1 }
    substance_counts.sort_by { |_, count| -count }.take(limit)
  end

  def get_one_time_substances
    substance_counts = Hash.new(0)
    @data.each { |entry| substance_counts[entry[:substance]] += 1 }
    substance_counts.select { |_, count| count == 1 }.keys.sort
  end

  def get_peak_month
    monthly = Hash.new(0)
    @data.each do |entry|
      month_key = entry[:timestamp].strftime('%Y-%m')
      monthly[month_key] += 1
    end
    monthly.max_by { |_, count| count }
  end

  def get_time_of_day_analysis
    periods = {
      'Morning (6-11)' => (6..11),
      'Afternoon (12-17)' => (12..17),
      'Evening (18-23)' => (18..23),
      'Night (0-5)' => (0..5)
    }

    analysis = {}
    periods.each { |period, _| analysis[period] = 0 }

    @data.each do |entry|
      hour = entry[:timestamp].hour
      period = periods.find { |_, range| range.include?(hour) }&.first
      analysis[period] += 1 if period
    end

    analysis
  end

  def get_hardest_day
    daily_counts = Hash.new(0)
    @data.each do |entry|
      date = entry[:timestamp].to_date
      daily_counts[date] += 1
    end

    return nil if daily_counts.empty?
    daily_counts.max_by { |_, count| count }
  end

  def get_streak_analysis
    past_data = @data.select { |entry| entry[:timestamp].to_date <= Date.today - 1 }
    return {} if past_data.empty?

    substance_dates = {}
    past_data.each do |entry|
      substance = entry[:substance]
      date = entry[:timestamp].to_date
      substance_dates[substance] ||= []
      substance_dates[substance] << date unless substance_dates[substance].include?(date)
    end

    streaks = {}
    substance_dates.each do |substance, dates|
      dates.sort!
      current_streak = 1
      max_streak = 1

      (1...dates.length).each do |i|
        if dates[i] == dates[i-1] + 1
          current_streak += 1
          max_streak = [max_streak, current_streak].max
        else
          current_streak = 1
        end
      end

      streaks[substance] = max_streak if max_streak > 1
    end

    streaks
  end

  def get_route_analysis
    routes = Hash.new { |h, k| h[k] = [] }
    @data.each do |entry|
      routes[entry[:substance]] << entry[:route]
    end
    routes
  end

  def get_peak_time_period(time_analysis)
    peak_period, peak_count = time_analysis.max_by { |_, count| count }

    {
      period: peak_period.split(' ')[0], # Just the time name
      count: peak_count
    }
  end

  def format_time_bars(time_analysis)
    max_count = time_analysis.values.max

    time_analysis.map do |period, count|
      percentage = max_count > 0 ? (count.to_f / max_count) * 100 : 0

      {
        label: period.split(' ')[0],
        value: "#{count} uses",
        percentage: percentage
      }
    end
  end

  def format_month_name(month_string)
    Date.strptime(month_string, '%Y-%m').strftime('%B')
  end

  def get_surprise_stat
    return nil if @data.empty?

    # Calculate various interesting statistics
    stats = []

    # Unique dates
    unique_dates = @data.map { |e| e[:timestamp].to_date }.uniq.count
    if unique_dates > 0
      stats << {
        title: "#{unique_dates} Different Days",
        subtitle: "of documented experiences",
        value: "#{unique_dates} days",
        flavor: "Spreading the joy around"
      }
    end

    # Weekend vs weekday usage
    weekend_count = @data.count { |e| [0, 6].include?(e[:timestamp].wday) }
    weekday_count = @data.count - weekend_count
    if weekend_count > weekday_count
      stats << {
        title: "Weekend Warrior",
        subtitle: "#{weekend_count} weekend experiences",
        value: "#{((weekend_count.to_f / @data.length) * 100).round(1)}%",
        flavor: "Saturday night's alright"
      }
    elsif weekday_count > weekend_count * 2
      stats << {
        title: "Weekday Rebel",
        subtitle: "#{weekday_count} weekday experiences",
        value: "#{((weekday_count.to_f / @data.length) * 100).round(1)}%",
        flavor: "Monday motivation"
      }
    end

    # Most common dose if numeric
    doses = @data.map { |e| e[:dose] }.compact
    numeric_doses = doses.select { |d| d.to_s.match(/^\d+\.?\d*$/) }.map(&:to_f)
    if numeric_doses.any?
      avg_dose = (numeric_doses.sum / numeric_doses.length).round(2)
      stats << {
        title: "Average Dose",
        subtitle: "when measurable",
        value: "#{avg_dose}",
        flavor: "Consistency is key"
      }
    end

    # Most active season
    seasons = { 'Winter' => 0, 'Spring' => 0, 'Summer' => 0, 'Fall' => 0 }
    @data.each do |entry|
      month = entry[:timestamp].month
      season = case month
               when 12, 1, 2 then 'Winter'
               when 3, 4, 5 then 'Spring'
               when 6, 7, 8 then 'Summer'
               when 9, 10, 11 then 'Fall'
               end
      seasons[season] += 1
    end

    peak_season, peak_count = seasons.max_by { |_, count| count }
    if peak_count > 0
      stats << {
        title: "#{peak_season} Person",
        subtitle: "#{peak_count} experiences in #{peak_season.downcase}",
        value: "#{((peak_count.to_f / @data.length) * 100).round(1)}%",
        flavor: "Seasonal affective enhancement"
      }
    end

    # Return random stat or nil
    stats.sample
  end

  def get_top_substances_subtitle(top_substances)
    return "No substances found" if top_substances.empty?

    top_name, top_count = top_substances.first
    total_uses = @data.length
    percentage = ((top_count.to_f / total_uses) * 100).round(1)

    "#{top_name} dominated with #{percentage}% of your usage"
  end
end