# frozen_string_literal: true module Granblue module Parsers # SuggestionParser extracts structured suggestions from wiki text # for use in batch entity import flows class SuggestionParser # Parse character wiki text into suggestion fields def self.parse_character(wiki_text) return {} if wiki_text.blank? data = parse_wiki_text(wiki_text) suggestions = {} suggestions[:name_en] = data['name'] if data['name'].present? suggestions[:name_jp] = data['jpname'] if data['jpname'].present? suggestions[:granblue_id] = data['id'] if data['id'].present? # Character ID (for linking related characters) if data['charid'].present? char_ids = data['charid'].scan(/\b\d{4}\b/) suggestions[:character_id] = char_ids if char_ids.any? end # Rarity suggestions[:rarity] = Wiki.rarities[data['rarity']] if data['rarity'].present? # Element suggestions[:element] = Wiki.elements[data['element']] if data['element'].present? # Gender suggestions[:gender] = Wiki.genders[data['gender']] if data['gender'].present? # Proficiencies if data['weapon'].present? profs = data['weapon'].split(',').map(&:strip) suggestions[:proficiency1] = Wiki.proficiencies[profs[0]] if profs[0] suggestions[:proficiency2] = Wiki.proficiencies[profs[1]] if profs[1] end # Races if data['race'].present? races = data['race'].split(',').map(&:strip) suggestions[:race1] = Wiki.races[races[0]] if races[0] suggestions[:race2] = Wiki.races[races[1]] if races[1] end # Stats suggestions[:min_hp] = data['min_hp'].to_i if data['min_hp'].present? suggestions[:max_hp] = data['max_hp'].to_i if data['max_hp'].present? suggestions[:max_hp_flb] = data['flb_hp'].to_i if data['flb_hp'].present? suggestions[:min_atk] = data['min_atk'].to_i if data['min_atk'].present? suggestions[:max_atk] = data['max_atk'].to_i if data['max_atk'].present? suggestions[:max_atk_flb] = data['flb_atk'].to_i if data['flb_atk'].present? # Uncap status suggestions[:flb] = Wiki.boolean.fetch(data['5star'], false) if data['5star'].present? suggestions[:ulb] = data['max_evo'].to_i == 6 if data['max_evo'].present? # Dates suggestions[:release_date] = parse_date(data['release_date']) if data['release_date'].present? suggestions[:flb_date] = parse_date(data['5star_date']) if data['5star_date'].present? suggestions[:ulb_date] = parse_date(data['6star_date']) if data['6star_date'].present? # External links suggestions[:gamewith] = data['link_gamewith'] if data['link_gamewith'].present? suggestions[:kamigame] = data['link_kamigame'] if data['link_kamigame'].present? suggestions.compact end # Parse weapon wiki text into suggestion fields def self.parse_weapon(wiki_text) return {} if wiki_text.blank? data = parse_wiki_text(wiki_text) suggestions = {} suggestions[:name_en] = data['name'] if data['name'].present? suggestions[:name_jp] = data['jpname'] if data['jpname'].present? suggestions[:granblue_id] = data['id'] if data['id'].present? # Rarity suggestions[:rarity] = Wiki.rarities[data['rarity']] if data['rarity'].present? # Element suggestions[:element] = Wiki.elements[data['element']] if data['element'].present? # Proficiency (weapon type) suggestions[:proficiency] = Wiki.proficiencies[data['type']] if data['type'].present? # Stats suggestions[:min_hp] = data['min_hp'].to_i if data['min_hp'].present? suggestions[:max_hp] = data['max_hp'].to_i if data['max_hp'].present? suggestions[:max_hp_flb] = data['flb_hp'].to_i if data['flb_hp'].present? suggestions[:min_atk] = data['min_atk'].to_i if data['min_atk'].present? suggestions[:max_atk] = data['max_atk'].to_i if data['max_atk'].present? suggestions[:max_atk_flb] = data['flb_atk'].to_i if data['flb_atk'].present? # Uncap status suggestions[:flb] = Wiki.boolean.fetch(data['4star'], false) if data['4star'].present? suggestions[:ulb] = Wiki.boolean.fetch(data['5star'], false) if data['5star'].present? # Dates suggestions[:release_date] = parse_date(data['release_date']) if data['release_date'].present? suggestions[:flb_date] = parse_date(data['4star_date']) if data['4star_date'].present? suggestions[:ulb_date] = parse_date(data['5star_date']) if data['5star_date'].present? # External links suggestions[:gamewith] = data['link_gamewith'] if data['link_gamewith'].present? suggestions[:kamigame] = data['link_kamigame'] if data['link_kamigame'].present? # Recruits (character recruited by this weapon) suggestions[:recruits] = data['recruit'] if data['recruit'].present? suggestions.compact end # Parse summon wiki text into suggestion fields def self.parse_summon(wiki_text) return {} if wiki_text.blank? data = parse_wiki_text(wiki_text) suggestions = {} suggestions[:name_en] = data['name'] if data['name'].present? suggestions[:name_jp] = data['jpname'] if data['jpname'].present? suggestions[:granblue_id] = data['id'] if data['id'].present? # Rarity suggestions[:rarity] = Wiki.rarities[data['rarity']] if data['rarity'].present? # Element suggestions[:element] = Wiki.elements[data['element']] if data['element'].present? # Stats suggestions[:min_hp] = data['min_hp'].to_i if data['min_hp'].present? suggestions[:max_hp] = data['max_hp'].to_i if data['max_hp'].present? suggestions[:max_hp_flb] = data['flb_hp'].to_i if data['flb_hp'].present? suggestions[:min_atk] = data['min_atk'].to_i if data['min_atk'].present? suggestions[:max_atk] = data['max_atk'].to_i if data['max_atk'].present? suggestions[:max_atk_flb] = data['flb_atk'].to_i if data['flb_atk'].present? # Uncap status suggestions[:flb] = Wiki.boolean.fetch(data['4star'], false) if data['4star'].present? suggestions[:ulb] = Wiki.boolean.fetch(data['5star'], false) if data['5star'].present? # Sub-aura suggestions[:subaura] = Wiki.boolean.fetch(data['subaura'], false) if data['subaura'].present? # Dates suggestions[:release_date] = parse_date(data['release_date']) if data['release_date'].present? suggestions[:flb_date] = parse_date(data['4star_date']) if data['4star_date'].present? suggestions[:ulb_date] = parse_date(data['5star_date']) if data['5star_date'].present? # External links suggestions[:gamewith] = data['link_gamewith'] if data['link_gamewith'].present? suggestions[:kamigame] = data['link_kamigame'] if data['link_kamigame'].present? suggestions.compact end # Parse wiki text into a key-value hash def self.parse_wiki_text(wiki_text) lines = wiki_text.split("\n") data = {} stop_loop = false lines.each do |line| next if stop_loop # Stop parsing at gameplay notes section if line.include?('Gameplay Notes') stop_loop = true next end next unless line[0] == '|' && line.size > 2 key, value = line[1..].split('=', 2).map(&:strip) data[key] = value if value.present? end data end # Parse a date string into a Date object def self.parse_date(date_str) Date.parse(date_str) rescue ArgumentError, TypeError nil end end end end