package model.doctorviruspatient;

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

import javafx.scene.paint.Color;
import model.Board;
import model.Entity;
import model.Square;
import model.firefighterscenario.Cloud;
import util.Position;
import util.PositionUtil;
import view.ViewElement;

public class Doctor implements Entity {
    private final int priority = 1;
    private Position position;
    private int age;
    private final Color viewColor = Color.RED;
    private static javafx.scene.image.Image cloudImage;

    static {
        try {
            cloudImage = new javafx.scene.image.Image(Cloud.class.getResource("/view/icons/virus/docteur.png").toExternalForm());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    // Statique car les médecins partagent les connaissances et les recherches
    private static List<Integer> knownVirusVariant = new ArrayList<Integer>();
    private static Map<Integer, Double> currentResearch = new HashMap<>(); // Map<variantId, % de recherche>

    public Doctor(Position p) {
        this.position = p;
    }

    public Doctor(Position p, int age) {
        this.position = p;
        this.age = age;
    }

    @Override
    public List<Position> nextTurn(Board<Square> board) {
        // Mettre à jour les recherches en cours
        updateCurrentResearch();

        // Interagir avec les positions adjacentes
        interactWithAdjacentPositions(PositionUtil.generateAllAdjacentPositions(position, board), board);
        
        return List.of();
    }

    /**
     * Met à jour toutes les recherches en cours en augmentant leur avancement de x%.
     * Si une recherche atteint ou dépasse 100%, elle est terminée.
     */
    private void updateCurrentResearch() {
        List<Integer> completedResearch = new ArrayList<>();
        
        for (Map.Entry<Integer, Double> entry : currentResearch.entrySet()) {
            int variantId = entry.getKey();
            double progress = entry.getValue() + 2.0;
            if (progress >= 100.0) {
                progress = 100.0;
                completedResearch.add(variantId);
            }
            currentResearch.put(variantId, progress);
        }

        // Traiter les recherches complétées
        for (int variantId : completedResearch) {
            currentResearch.remove(variantId);
            knownVirusVariant.add(variantId);
            System.out.println("Recherche terminée pour le variant ID: " + variantId);
        }
    }

    private List<Position> interactWithAdjacentPositions(List<Position> adjacentPositions, Board<Square> board) {
        List<Position> result = new ArrayList<>();
        for (Position p : adjacentPositions) {
            if (board.doesSquareContainEntity(p, Patient.class)) {
                handleEncounterWithPatient(p, board);
            }
        }
        return result;
    }

    private void handleEncounterWithPatient(Position p, Board<Square> board) {
        if (board.doesSquareContainEntity(p, Patient.class)) {
            Patient patient = (Patient) board.getStates(p).getEntities().stream()
                    .filter(e -> e instanceof Patient)
                    .findFirst()
                    .orElse(null);
            if (patient != null && patient.isInfected()) {
                Virus virus = patient.getVirus();
                if (virus != null) {
                    int variantId = virus.getVariantId();
                    if (knownVirusVariant.contains(variantId)) {
                        patient.cure();
                    } else {
                        // Si la variante n'est pas connue et pas en cours de recherche, l'ajouter à la recherche
                        if (!currentResearch.containsKey(variantId)) {
                            currentResearch.put(variantId, 0.0);
                            System.out.println("Nouvelle variante détectée! Variant ID: " + variantId + ". Recherche commencée.");
                        }
                    }
                }
            }
        }
    }

    @Override
    public Position getPosition() {
        return this.position;
    }

    @Override
    public void setPosition(Position p) {
        this.position = p;
    }

    @Override
    public int getAge() {
        return this.age;
    }

    @Override
    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public void incrementAge() {
        this.age += 1;
    }

    @Override
    public Color getViewColor() {
        return this.viewColor;
    }

    @Override
    public int getPriority() {
        return this.priority;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Doctor) {
            Doctor other = (Doctor) obj;
            return this.position.equals(other.getPosition());
        } else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        return Objects.hash(position);
    }

    @Override
    public ViewElement getViewElement() {
        return new ViewElement (cloudImage);
    }


}