#pragma once

#include <cstddef>
#include <string>

#include "Ship/CargoDamageVisitor.h"

#include <Core/DifficultLvlStrategy.h>

struct Cargo {
    Cargo(size_t amount);
    virtual ~Cargo() = default;
    Cargo(const Cargo&) = default;
    Cargo(Cargo&&) = default;
    Cargo& operator=(const Cargo&) = default;
    Cargo& operator=(Cargo&&) = default;

    auto operator<=>(const Cargo&) const = default;
    virtual size_t amount() const { return _amount; }
    virtual size_t& amount() { return _amount; }

    virtual size_t getPrice() const = 0;
    virtual const std::string& name() const = 0;
    virtual void accept(const CargoDamageVisitor& visitor) = 0;

protected:
    Cargo() = default;

private:
    size_t _amount;
};

struct Fruit : public Cargo {
    static constexpr int BASE_PRICE = 10;

    using Cargo::Cargo;

    size_t getPrice() const override;
    const std::string& name() const override;
    void accept(const CargoDamageVisitor& visitor) override;
};

struct Item : public Cargo {
    static constexpr int BASE_PRICE = 100;

    using Cargo::Cargo;

    size_t getPrice() const override;
    const std::string& name() const override;
    void accept(const CargoDamageVisitor& visitor) override;
};

struct Alcohol : public Cargo {
    static constexpr int MAX_POWER = 96;
    static constexpr int BASE_PRICE = 100;
    int power;

    Alcohol(size_t amount, int power);

    size_t getPrice() const override;
    const std::string& name() const override;
    void accept(const CargoDamageVisitor& visitor) override;
};