#pragma once

#include <memory>
#include <string>
#include <vector>

#include <Core/TimeObserver.h>
#include "Ship/Cargo.h"

class Time;

class Ship : public TimeObserver {
public:
    enum class StatusCode {
        OK,
        MissingCargo,
        LackOfSpace
    };

    Ship(Time* time, const std::string& name, int capacity, int crew);
    ~Ship();
    Ship(const Ship&) = default;
    Ship(Ship&&) = default;
    Ship& operator=(const Ship&) = default;
    Ship& operator=(Ship&&) = default;

    // Override from TimeObserver
    void nextDay() override;

    std::string& name() { return _name; }
    const std::string& name() const { return _name; }
    int crew() const { return _crew; }

    void printCargo() const;

    Cargo* load(std::unique_ptr<Cargo>&& cargo, StatusCode& code) noexcept;
    void unload(const Cargo& cargo, StatusCode& code) noexcept;

    // May throw
    Cargo* load(std::unique_ptr<Cargo>&& cargo);
    void unload(const Cargo& cargo);

private:
    bool consume(const std::string& cargoName);
    void rebel();

    Time* _time;
    std::string _name;
    int _capacity;
    int _crew;
    std::vector<std::unique_ptr<Cargo>> _cargoes;
};
