require 'terminal-table'
require 'fastlane_core/print_table'

module Fastlane
  class PrettyTable
    def self.print(data:, columns: nil, title: nil, column_names: nil, expand: nil)
      if data.is_a?(Hash)
        columns ||= data.keys
        print_rows(
          data: data.filter { |k, v| columns.include?(k) }.map { |k, v| { key: (column_names ? column_names[k] : nil) || k, value: v } },
          columns: [:key, :value],
          title: title,
          header: false,
          expand: expand.nil? ? true : expand
        )
      else
        columns ||= data.first.keys
        print_rows(
          data: data,
          columns: columns,
          title: title,
          column_names: column_names,
          header: true,
          expand: expand.nil? ? false : expand
        )
      end
    end

    def self.print_rows(data:, columns:, title: nil, column_names: nil, header: true, expand: false)
      headings = header ? columns.map do |column_key|
        if column_names.nil? || column_names[column_key].nil?
          column_key.to_s.split("_").map(&:capitalize).join(" ")
        else
          column_names[column_key]
        end
      end : []

      rows = data.map do |row|
        column_values = columns.map do |column_key|
          if column_key == columns.first
            row[column_key].to_s.cyan
          else
            stringify(row[column_key], expand: expand)
          end
        end
        column_values
      end

      transformed_rows = FastlaneCore::PrintTable.transform_output(rows)
      table = Terminal::Table.new(
        headings: headings,
        title: title.green,
        rows: transformed_rows
      )

      puts("")
      puts(table)
      puts("")
    end

    def self.stringify(val, expand: false)
      if val.is_a?(Integer)
        val.to_s.yellow
      elsif val.is_a?(Array)
        if val.empty?
          ''
        elsif expand
          val.map { |v| stringify(v, expand: expand) }.join(", ")
        else
          val.count.to_s.green
        end
      elsif val.is_a?(Hash)
        if val.empty?
          ''
        elsif expand
          val.map { |k, v| "#{k.to_s.magenta} -> #{stringify(v, expand: expand)}" }.join("; ")
        else
          val.keys.count.to_s.green
        end
      elsif val
        val.to_s
      else
        ""
      end
    end
  end
end
