#pragma once

#include <Core/DifficultLvlStrategy.h>
#include <Ship/Ship.h>

#include <memory>
#include <string>

template <typename DamageVisitor>
class Enemy {
public:
    Enemy(const std::string& name, std::unique_ptr<Ship>&& ship, std::unique_ptr<DifficultLvlStrategy<Ship, int>>&& strategy, DamageVisitor visitor);

    int attack(Ship& playerShip) override;
    Ship& getShip() { return *_ship; }
    const Ship& getShip() const { return *_ship; }

private:
    std::string _name;
    std::unique_ptr<Ship> _ship;
    std::unique_ptr<DifficultLvlStrategy<Ship, int>> _strategy;
    DamageVisitor _damageVisitor;
};

template <typename DamageVisitor>
Enemy<DamageVisitor>::Enemy(const std::string& name, std::unique_ptr<Ship>&& ship, std::unique_ptr<DifficultLvlStrategy<Ship, int>>&& strategy, DamageVisitor visitor)
    : _name(name), _ship(std::move(ship)), _strategy(std::move(strategy)), _damageVisitor(visitor) {}

template <typename DamageVisitor>
int Enemy<DamageVisitor>::attack(Ship& playerShip) {
    if (const auto damage = _strategy->handle(playerShip)) {
        for (auto& cargo : playerShip.cargoes()) {
            cargo->accept(_damageVisitor);
        }
        return damage;
    }

    return 0;
}
