/*
 * Copyright (C) 2025-2026  Tim Zimmermann <tim@aglais.org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.aglais.zms.ui.tab;

import org.aglais.zms.AglaisZMS;
import org.aglais.zms.db.core.model.Species;
import org.aglais.zms.gbif.GBIFAPI;
import org.aglais.zms.gbif.GBIFSpeciesIUCNRedListCategory;
import org.aglais.zms.gbif.GBIFSpeciesMatch;
import org.aglais.zms.i18n.InterpolatingResourceBundle;
import org.aglais.zms.ui.component.IUCNStatus;
import org.aglais.zms.ui.util.SpeciesUtil;
import org.aglais.zms.util.Log;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.util.*;

/**
 * Dashboard tab that shows the main overview panel with key information and metrics.
 */
public class DashboardTab extends Tab {

    private static final String LOG_TAG = DashboardTab.class.getSimpleName();

    private JPanel contentPane;
    private JLabel currentlyKeptSpeciesLabel;
    private JLabel currentlyKeptEndangeredSpeciesLabel;
    private JLabel currentlyKeptPopulationsLabel;
    private JLabel noLongerKeptSpeciesLabel;
    private final HashMap<Integer, IUCNStatus.Status> iucnStatusCache = new HashMap<>();

    /**
     * Constructs a new DashboardTab instance. This tab represents the main dashboard view
     * in the application, providing an overview of key information and metrics.
     *
     * @param zms The main application instance of {@link AglaisZMS} to associate with this tab
     */
    public DashboardTab(AglaisZMS zms) {
        super(zms);
    }

    @Override
    public void onShow() {
        InterpolatingResourceBundle uiBundle = (InterpolatingResourceBundle) ResourceBundle.getBundle("ui");

        currentlyKeptSpeciesLabel.setText(uiBundle.getString("stat_currently_kept_species",
                "..."));
        currentlyKeptPopulationsLabel.setText(uiBundle.getString("stat_currently_kept_populations",
                "..."));
        currentlyKeptEndangeredSpeciesLabel.setText(uiBundle.getString("stat_currently_kept_endangered_species",
                "..."));
        noLongerKeptSpeciesLabel.setText(uiBundle.getString("stat_no_longer_kept_species",
                "..."));
    }

    @Override
    public void onShowAsync() {
        InterpolatingResourceBundle uiBundle = (InterpolatingResourceBundle) ResourceBundle.getBundle("ui");
        int populationsCount = 0;
        List<Species> speciesList = zms.getClient().getAllSpecies();
        Set<Species> keptSpecies = new HashSet<>();

        for (Species species : speciesList) {
            int speciesPopulationsCount = SpeciesUtil.getAlivePopulationsCount(zms, species);

            if (speciesPopulationsCount > 0) {
                populationsCount += speciesPopulationsCount;

                keptSpecies.add(species);

                final int currentPopulationsCount = populationsCount;
                SwingUtilities.invokeLater(() -> {
                    currentlyKeptSpeciesLabel.setText(uiBundle.getString("stat_currently_kept_species",
                            keptSpecies.size()));
                    currentlyKeptPopulationsLabel.setText(uiBundle.getString("stat_currently_kept_populations",
                            currentPopulationsCount));
                });
            }
        }

        SwingUtilities.invokeLater(() -> {
            noLongerKeptSpeciesLabel.setText(uiBundle.getString("stat_no_longer_kept_species",
                    speciesList.size() - keptSpecies.size()));
        });

        List<Species> keptEndangeredSpecies = new ArrayList<>();
        for (Species species : keptSpecies) {
            IUCNStatus.Status status = IUCNStatus.Status.NE;
            if (iucnStatusCache.containsKey(species.getID())) {
                status = iucnStatusCache.get(species.getID());
            } else {
                try {
                    GBIFSpeciesMatch match = GBIFAPI.matchSpecies(species.getScientificName());
                    if (match != null) {
                        GBIFSpeciesIUCNRedListCategory redListCategory = GBIFAPI.getSpeciesIUCNRedListCategory(
                                match.usageKey());
                        if (redListCategory != null) {
                            status = IUCNStatus.Status.valueOf(redListCategory.code().toUpperCase());
                        }
                    }
                } catch (Exception e) {
                    Log.e(LOG_TAG, "Failed to query species: " + species.getScientificName(), e);
                }
            }

            iucnStatusCache.put(species.getID(), status);
            if (status.ordinal() > IUCNStatus.Status.LC.ordinal()) {
                keptEndangeredSpecies.add(species);

                SwingUtilities.invokeLater(() -> currentlyKeptEndangeredSpeciesLabel.setText(
                        uiBundle.getString("stat_currently_kept_endangered_species",
                                keptEndangeredSpecies.size())));
            }
        }
    }

    @Override
    public @NotNull JComponent getContentPane() {
        return contentPane;
    }
}
