module ExcelReports
  class Worksheet
    attr_accessor :workbook, :data, :header_data

    def self.build(workbook, data = nil, header_data = nil)
      new(workbook, data, header_data).tap do |worksheet|
        worksheet.build
      end
    end

    def initialize(workbook, data = nil, header_data = nil)
      @workbook = workbook
      @data = data
      @header_data = header_data
    end

    def build
      workbook.add_worksheet(name: title) do |sheet|
        fill_content(sheet)
        format(sheet)
        style(sheet)
      end
    end

    module Styles
      def self.merge_all(*styles)
        styles.each_with_object({}) { |style, combined| combined.deep_merge!(style) }
      end

      BOLD = { b: true }
      ITALIC = { i: true }
      UNDERLINE = { u: true }
      BG_GRAY = { bg_color: "C0C0C0" }
      BG_LIGHT_BLUE = { bg_color: "97CBFC" }
      BG_YELLOW = { bg_color: "FFFF9E" }
      COLOR_WHITE = { fg_color: "FFFFFF" }
      COLOR_BLUE = { fg_color: "0000FF" }
      COLOR_RED = { fg_color: "FF0000" }
      THIN_BLACK_BORDER = { border: { style: :thin, color: "000000" } }
      THICK_BLACK_BORDER = { border: { style: :thick, color: "000000" } }
      VERTICAL_CENTER = { alignment: { vertical: :center } }
      HORIZONTAL_CENTER = { alignment: { horizontal: :center } }
      HORIZONTAL_LEFT = { alignment: { horizontal: :left } }
      HORIZONTAL_RIGHT = { alignment: { horizontal: :right } }
      FULLY_CENTERED = merge_all(HORIZONTAL_CENTER, VERTICAL_CENTER)
      WRAP_TEXT = { alignment: { wrap_text: true } }
      TABLE_HEADER = merge_all(Styles::BG_LIGHT_BLUE, Styles::BOLD, Styles::THICK_BLACK_BORDER, Styles::FULLY_CENTERED, Styles::WRAP_TEXT, { sz: 8 })
      TABLE_DATA = merge_all(Styles::THICK_BLACK_BORDER, Styles::WRAP_TEXT, { sz: 10 })
      PROGRAM_HEADER = merge_all(Styles::BG_LIGHT_BLUE, Styles::BOLD, Styles::THICK_BLACK_BORDER, Styles::HORIZONTAL_CENTER, Styles::WRAP_TEXT, { sz: 12 })
      HEADER_DATA = merge_all(Styles::THICK_BLACK_BORDER, Styles::WRAP_TEXT, Styles::HORIZONTAL_LEFT, { sz: 10 })
    end
  end
end
