#include "arena_ui.hpp"
#include "easings.hpp"
#include "sound.hpp"
#include <fmt/xchar.h>

namespace arena {
  using namespace guecs;

  ArenaUI::ArenaUI(shared_ptr<DinkyECS::World> world, DinkyECS::Entity entity_id)
    : $world(world),
      $entity_id(entity_id),
      $config(world->get_the<components::GameConfig>())
  {
    $status.position(0, 0, BOSS_VIEW_X, SCREEN_HEIGHT);
    $status.layout(
        "[main_status]"
        "[(150)status_3|(150)status_4]"
        "[(150)status_5|(150)status_6]"
        "[(150)status_7|(150)status_8]");

    $overlay.position(BOSS_VIEW_X, BOSS_VIEW_Y,
        BOSS_VIEW_WIDTH, BOSS_VIEW_HEIGHT);

    $overlay.layout("[_|=(256,256)enemy|_]");

    $sounds = $world->get<components::Sound>($entity_id);
    $combat = $world->get<components::Combat>($entity_id);
    $sprite_config = $world->get<components::Sprite>($entity_id);
  }

  void ArenaUI::configure_sprite() {
    $animation = $world->get<components::Animation>($entity_id);
    $animation.frame_width = $sprite_config.width;

    auto enemy_id = $overlay.entity("enemy");
    auto& enemy_image = $overlay.get<Sprite>(enemy_id);

    sf::IntRect frame_rect{{0,0},{$sprite_config.width, $sprite_config.height}};
    enemy_image.sprite->setTextureRect(frame_rect);
  }

  void ArenaUI::configure_background() {
    if($world->has<components::BossFight>($entity_id)) {
      auto& boss = $world->get<components::BossFight>($entity_id);

      $entity_background = textures::get(boss.background);
      $entity_background.sprite->setPosition({BOSS_VIEW_X, BOSS_VIEW_Y});
      $status.world().set_the<Background>({$status.$parser});

      $entity_has_stage = true;

      if(boss.stage) {
        $entity_stage = textures::get(*boss.stage);
      } else {
        $entity_stage = textures::get("devils_fingers_background");
      }

      $entity_stage.sprite->setPosition({BOSS_VIEW_X, BOSS_VIEW_Y});
    } else {
      $entity_has_stage = false;
      $entity_background = textures::get("devils_fingers_background");
      $entity_background.sprite->setPosition({BOSS_VIEW_X, BOSS_VIEW_Y});
      $status.world().set_the<Background>({$status.$parser});
    }
  }

  void ArenaUI::configure_gui() {
    for(auto& [name, cell] : $status.cells()) {
      auto button = $status.entity(name);
      $status.set<Rectangle>(button, {});
      $status.set<Clickable>(button, {
          [this, name](auto, auto){
            dbc::log(fmt::format("STATUS: {}", name));
          }
      });
      if(name == "main_status") {
        $status.set<Textual>(button, {fmt::format(L"HP: {}", $combat.hp)});
      } else {
        $status.set<Label>(button, {L"Attack"});
      }
    }
    $status.init();

    for(auto& [name, cell] : $overlay.cells()) {
      auto region = $overlay.entity(name);
      $overlay.set<Clickable>(region, {
          [this, name](auto, auto){
            dbc::log(fmt::format("OVERLAY: {}", name));
          }
      });

      if(name == "enemy") {
        $overlay.set<Sprite>(region, {$sprite_config.name, 20});
      }
    }

    $overlay.init();

    configure_sprite();
  }

  void ArenaUI::init() {
    // background must come first
    configure_background();
    configure_gui();
  }

  void ArenaUI::render(sf::RenderWindow& window) {
    window.draw(*$entity_background.sprite);

    if($entity_has_stage) {
      window.draw(*$entity_stage.sprite);
    }

    $status.render(window);
    $overlay.render(window);
  }

  bool ArenaUI::mouse(float x, float y) {
    if($status.mouse(x, y)) {
      dbc::log("STATUS button pressed");
    }

    if($overlay.mouse(x, y)) {
      $animation.play();
      sound::play("Sword_Hit_1");
      $entity_hit = !$entity_hit;
      $combat.hp--;
    }

    return false;
  }
}