# frozen_string_literal: true module Notare class TableStyle attr_reader :name, :borders, :shading, :cell_margins, :align BORDER_STYLES = %w[single double dotted dashed triple none nil].freeze BORDER_POSITIONS = %i[top bottom left right insideH insideV].freeze ALIGNMENTS = %i[left center right].freeze def initialize(name, borders: nil, shading: nil, cell_margins: nil, align: nil) @name = name @borders = normalize_borders(borders) @shading = normalize_color(shading) @cell_margins = normalize_cell_margins(cell_margins) @align = validate_align(align) end def style_id name.to_s.split("_").map(&:capitalize).join end def display_name name.to_s.split("_").map(&:capitalize).join(" ") end private def normalize_borders(borders) return nil if borders.nil? return :none if borders == :none # Check if it's a per-edge configuration if borders.keys.any? { |k| BORDER_POSITIONS.include?(k) } borders.transform_values { |v| normalize_single_border(v) } else # Single border config applied to all edges normalize_single_border(borders) end end def normalize_single_border(border) return :none if border == :none || border[:style] == "none" style = border[:style] || "single" unless BORDER_STYLES.include?(style) raise ArgumentError, "Invalid border style: #{style}. Use #{BORDER_STYLES.join(", ")}" end { style: style, color: normalize_color(border[:color]) || "000000", size: border[:size] || 4 } end def normalize_color(color) return nil if color.nil? hex = color.to_s.sub(/^#/, "").upcase return hex if hex.match?(/\A[0-9A-F]{6}\z/) raise ArgumentError, "Invalid color: #{color}. Use 6-digit hex (e.g., 'FF0000')" end def normalize_cell_margins(margins) return nil if margins.nil? if margins.is_a?(Hash) margins.slice(:top, :bottom, :left, :right) else margins.to_i end end def validate_align(align) return nil if align.nil? return align if ALIGNMENTS.include?(align) raise ArgumentError, "Invalid alignment: #{align}. Use #{ALIGNMENTS.join(", ")}" end end end