package autumn_2023.module.complex;

import adf.core.agent.communication.MessageManager;
import adf.core.agent.communication.standard.bundle.MessageUtil;
import adf.core.agent.communication.standard.bundle.StandardMessagePriority;
import adf.core.agent.communication.standard.bundle.information.MessageCivilian;
import adf.core.agent.develop.DevelopData;
import adf.core.agent.info.AgentInfo;
import adf.core.agent.info.ScenarioInfo;
import adf.core.agent.info.WorldInfo;
import adf.core.agent.module.ModuleManager;
import adf.core.agent.precompute.PrecomputeData;
import adf.core.component.communication.CommunicationMessage;
import adf.core.component.module.complex.FireTargetAllocator;
import autumn_2023.module.comm.infomation.MessageCost;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import rescuecore2.standard.entities.AmbulanceTeam;
import rescuecore2.standard.entities.Civilian;
import rescuecore2.standard.entities.FireBrigade;
import rescuecore2.worldmodel.EntityID;

public class AuctionFireTargetAllocator extends FireTargetAllocator{

    // 分散エージェントからの埋没市民のメッセージリスト
    private List<EntityID> receivedAgentCivilians;
    private List<EntityID> finishreceivedCivilians;

    // 分散エージェントからのコストのメッセージリスト
    private List<MessageCost> rescueCosts;
    private Map<EntityID, EntityID> rescueResult;

    public AuctionFireTargetAllocator(AgentInfo ai, WorldInfo wi, ScenarioInfo si, ModuleManager moduleManager, DevelopData developData) 
    {
        super(ai, wi, si, moduleManager, developData);

        this.receivedAgentCivilians = new ArrayList<>();
        this.finishreceivedCivilians = new ArrayList<>();
        this.rescueCosts = new ArrayList<>();
        this.rescueResult = new HashMap<>();
    }


    @Override
    public FireTargetAllocator resume(PrecomputeData precomputeData) 
    {
        super.resume(precomputeData);

        return this;
    }


    @Override
    public FireTargetAllocator preparate() 
    {
        super.preparate();

        return this;
    }


    @Override
    public Map<EntityID, EntityID> getResult() 
    {
        return this.rescueResult;
    }


    @Override
    public FireTargetAllocator calc() 
    {

        return this;
    }


    @Override
    public FireTargetAllocator updateInfo(MessageManager messageManager) 
    {
        super.updateInfo(messageManager);

        // 受信処理
        // そのステップで受信した(前ステップで送信された)メッセージ一覧
        List<CommunicationMessage> messages = messageManager.getReceivedMessageList();
        for(CommunicationMessage mes : messages) 
        {
        // mesが市民の情報であれば
        if (mes instanceof MessageCivilian) 
        {
            MessageCivilian mesCiv = (MessageCivilian) mes;
            if(mesCiv.getSendingPriority() == StandardMessagePriority.HIGH)
            {
                MessageUtil.reflectMessage(this.worldInfo, mesCiv);
                if (this.worldInfo.getEntity(mesCiv.getSenderID()) instanceof AmbulanceTeam 
                    || this.worldInfo.getEntity(mesCiv.getSenderID()) instanceof FireBrigade) 
                {
                    if(!receivedAgentCivilians.contains(mesCiv.getAgentID())
                        || !finishreceivedCivilians.contains(mesCiv.getAgentID()))
                    {
                        receivedAgentCivilians.add(mesCiv.getAgentID());
                    }
                }
            }
        }
        // mesがコストの情報であれば
        if (mes instanceof MessageCost) {
            MessageCost mesCos = (MessageCost) mes;
            if (this.worldInfo.getEntity(mesCos.getSenderID()) instanceof FireBrigade) 
            {
                rescueCosts.add(mesCos);
            }
        }
        }

        // 送信処理
        // 埋没している市民の情報の送信
        for(EntityID res : receivedAgentCivilians) 
        {
            messageManager.addMessage(new MessageCivilian(true, StandardMessagePriority.HIGH, (Civilian)this.worldInfo.getEntity(res)));
            finishreceivedCivilians.add(res);
        }
        receivedAgentCivilians.clear();

        return this;
    }
}
