// enemic.cpp - Implementació d'enemics (ORNIs)
// © 1999 Visente i Sergi (versió Pascal)
// © 2025 Port a C++20 amb SDL3

#include "game/entities/enemic.hpp"
#include "core/graphics/shape_loader.hpp"
#include "core/rendering/shape_renderer.hpp"
#include "game/constants.hpp"
#include <cmath>
#include <cstdlib>
#include <iostream>

Enemic::Enemic(SDL_Renderer *renderer)
    : renderer_(renderer), centre_({0.0f, 0.0f}), angle_(0.0f),
      velocitat_(0.0f), drotacio_(0.0f), rotacio_(0.0f), esta_(false) {

  // [NUEVO] Carregar forma compartida des de fitxer
  forma_ = Graphics::ShapeLoader::load("enemy_pentagon.shp");

  if (!forma_ || !forma_->es_valida()) {
    std::cerr << "[Enemic] Error: no s'ha pogut carregar enemy_pentagon.shp"
              << std::endl;
  }
}

void Enemic::inicialitzar() {
  // Inicialitzar enemic (pentàgon)
  // Copiat de joc_asteroides.cpp línies 41-54

  // [NUEVO] Ja no cal crear_poligon_regular - la geometria es carrega del
  // fitxer Només inicialitzem l'estat de la instància

  // Posició aleatòria dins de l'àrea de joc
  centre_.x = static_cast<float>((std::rand() % 580) + 30); // 30-610
  centre_.y = static_cast<float>((std::rand() % 420) + 30); // 30-450

  // Angle aleatori de moviment
  angle_ = (std::rand() % 360) * Constants::PI / 180.0f;

  // Velocitat (2 px/frame original * 20 FPS = 40 px/s)
  velocitat_ = 40.0f;

  // Rotació visual aleatòria (rad/s)
  // Original Pascal: random * 0.1 rad/frame * 20 FPS ≈ 2 rad/s
  drotacio_ = (static_cast<float>(std::rand()) / RAND_MAX) * 2.0f;
  rotacio_ = 0.0f;

  // Activar
  esta_ = true;
}

void Enemic::actualitzar(float delta_time) {
  if (esta_) {
    // Moviment autònom
    mou(delta_time);

    // Rotació visual (time-based: drotacio_ està en rad/s)
    rotacio_ += drotacio_ * delta_time;
  }
}

void Enemic::dibuixar() const {
  if (esta_ && forma_) {
    // [NUEVO] Usar render_shape en lloc de rota_pol
    Rendering::render_shape(renderer_, forma_, centre_, rotacio_, 1.0f, true);
  }
}

void Enemic::mou(float delta_time) {
  // Moviment autònom d'ORNI (enemic pentàgon)
  // Basat EXACTAMENT en el codi Pascal original: ASTEROID.PAS lines 279-293
  // Copiat EXACTAMENT de joc_asteroides.cpp línies 348-394
  //
  // IMPORTANT: El Pascal original NO té canvi aleatori continu!
  // Només ajusta l'angle quan toca una paret.

  // Calcular nova posició PROPUESTA (time-based, però lògica Pascal)
  // velocitat_ ja està en px/s (40 px/s), multiplicar per delta_time
  float velocitat_efectiva = velocitat_ * delta_time;

  // Calcular desplaçament (angle-PI/2 perquè angle=0 apunta amunt)
  float dy = velocitat_efectiva * std::sin(angle_ - Constants::PI / 2.0f);
  float dx = velocitat_efectiva * std::cos(angle_ - Constants::PI / 2.0f);

  float new_y = centre_.y + dy;
  float new_x = centre_.x + dx;

  // Obtenir límits de la zona de joc
  float min_x, max_x, min_y, max_y;
  Constants::obtenir_limits_zona(min_x, max_x, min_y, max_y);

  // Lògica Pascal: Actualitza Y si dins, sinó ajusta angle aleatòriament
  // if (dy>marge_dalt) and (dy<marge_baix) then orni.centre.y:=round(Dy)
  // else orni.angle:=orni.angle+(random(256)/512)*(random(3)-1);
  if (new_y > min_y && new_y < max_y) {
    centre_.y = new_y;
  } else {
    // Pequeño ajuste aleatorio: (random(256)/512)*(random(3)-1)
    // random(256) = 0..255, /512 = 0..0.498
    // random(3) = 0,1,2, -1 = -1,0,1
    // Resultado: ±0.5 rad aprox
    float rand1 = (static_cast<float>(std::rand() % 256) / 512.0f);
    int rand2 = (std::rand() % 3) - 1; // -1, 0, o 1
    angle_ += rand1 * static_cast<float>(rand2);
  }

  // Lògica Pascal: Actualitza X si dins, sinó ajusta angle aleatòriament
  // if (dx>marge_esq) and (dx<marge_dret) then orni.centre.x:=round(Dx)
  // else orni.angle:=orni.angle+(random(256)/512)*(random(3)-1);
  if (new_x > min_x && new_x < max_x) {
    centre_.x = new_x;
  } else {
    float rand1 = (static_cast<float>(std::rand() % 256) / 512.0f);
    int rand2 = (std::rand() % 3) - 1;
    angle_ += rand1 * static_cast<float>(rand2);
  }

  // Nota: La rotació visual (rotacio_ += drotacio_) ja es fa a actualitzar()
}
