{% extends "framework_modern.html" %}
{% load static %}
{% load envipytags %}
{% block content %}

  {% block action_modals %}
    {% include "modals/objects/edit_model_modal.html" %}
    {% include "modals/objects/evaluate_model_modal.html" %}
    {% include "modals/objects/retrain_model_modal.html" %}
    {% include "modals/objects/generic_delete_modal.html" %}
  {% endblock action_modals %}

  <!-- Include required libs -->
  <script src="https://d3js.org/d3.v5.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/c3@0.7.20/c3.min.js"></script>
  <link
    href="https://cdn.jsdelivr.net/npm/c3@0.7.20/c3.min.css"
    rel="stylesheet"
  />

  <div class="space-y-2 p-4">
    <!-- Header Section -->
    <div class="card bg-base-100">
      <div class="card-body">
        <div class="flex items-center justify-between">
          <h2 class="card-title text-2xl">{{ model.name }}</h2>
          <div id="actionsButton" class="dropdown dropdown-end hidden">
            <div tabindex="0" role="button" class="btn btn-ghost btn-sm">
              <svg
                xmlns="http://www.w3.org/2000/svg"
                width="16"
                height="16"
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                stroke-width="2"
                stroke-linecap="round"
                stroke-linejoin="round"
                class="lucide lucide-wrench"
              >
                <path
                  d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"
                />
              </svg>
              Actions
            </div>
            <ul
              tabindex="-1"
              class="dropdown-content menu bg-base-100 rounded-box z-50 w-52 p-2"
            >
              {% block actions %}
                {% include "actions/objects/model.html" %}
              {% endblock %}
            </ul>
          </div>
        </div>
        <p class="mt-2">{{ model.description }}</p>
      </div>
    </div>

    {% if model|classname == 'MLRelativeReasoning' or model|classname == 'RuleBasedRelativeReasoning' %}
      <!-- Rule Packages -->
      <div class="collapse-arrow bg-base-200 collapse">
        <input type="checkbox" checked />
        <div class="collapse-title text-xl font-medium">Rule Packages</div>
        <div class="collapse-content">
          <ul class="menu bg-base-100 rounded-box w-full">
            {% for p in model.rule_packages.all %}
              <li>
                <a href="{{ p.url }}" class="hover:bg-base-200">{{ p.name }}</a>
              </li>
            {% endfor %}
          </ul>
        </div>
      </div>
    {% endif %}
    <!-- Reaction Packages -->
    <div class="collapse-arrow bg-base-200 collapse">
      <input type="checkbox" checked />
      <div class="collapse-title text-xl font-medium">Reaction Packages</div>
      <div class="collapse-content">
        <ul class="menu bg-base-100 rounded-box w-full">
          {% for p in model.data_packages.all %}
            <li>
              <a href="{{ p.url }}" class="hover:bg-base-200">{{ p.name }}</a>
            </li>
          {% endfor %}
        </ul>
      </div>
    </div>
    {% if model.eval_packages.all|length > 0 %}
      <!-- Eval Packages -->
      <div class="collapse-arrow bg-base-200 collapse">
        <input type="checkbox" checked />
        <div class="collapse-title text-xl font-medium">Eval Packages</div>
        <div class="collapse-content">
          <ul class="menu bg-base-100 rounded-box w-full">
            {% for p in model.eval_packages.all %}
              <li>
                <a href="{{ p.url }}" class="hover:bg-base-200">{{ p.name }}</a>
              </li>
            {% endfor %}
          </ul>
        </div>
      </div>
    {% endif %}
    <!-- Model Status -->
    <div class="collapse-arrow bg-base-200 collapse">
      <input type="checkbox" checked />
      <div class="collapse-title text-xl font-medium">Model Status</div>
      <div class="collapse-content">{{ model.status }}</div>
    </div>

    {% if model.ready_for_prediction %}
      <!-- Predict Panel -->
      <div class="collapse-arrow bg-base-200 collapse">
        <input type="checkbox" checked />
        <div class="collapse-title text-xl font-medium" id="predictTitle">
          Predict
        </div>
        <div class="collapse-content">
          <div class="form-control">
            <div class="join w-full">
              <input
                id="smiles-to-predict"
                type="text"
                class="input input-bordered join-item grow"
                placeholder="CCN(CC)C(=O)C1=CC(=CC=C1)C"
              />
              <button
                class="btn btn-primary join-item"
                type="button"
                id="predict-button"
              >
                Predict!
              </button>
            </div>
          </div>
          <div id="predictLoading" class="mt-2 flex hidden justify-center">
            <div class="h-8 w-8">
              {% include "components/loading-spinner.html" %}
            </div>
          </div>
          <div id="predictResultTable" class="mt-4"></div>
        </div>
      </div>
    {% endif %}

    {% if model.ready_for_prediction and model.app_domain %}
      <!-- App Domain -->
      <div class="collapse-arrow bg-base-200 collapse">
        <input type="checkbox" checked />
        <div class="collapse-title text-xl font-medium">
          Applicability Domain Assessment
        </div>
        <div class="collapse-content">
          <div class="form-control">
            <div class="join w-full">
              <input
                id="smiles-to-assess"
                type="text"
                class="input input-bordered join-item grow"
                placeholder="CCN(CC)C(=O)C1=CC(=CC=C1)C"
              />
              <button
                class="btn btn-primary join-item"
                type="button"
                id="assess-button"
              >
                Assess!
              </button>
            </div>
          </div>
          <div id="appDomainLoading" class="mt-2 flex hidden justify-center">
            <div class="h-8 w-8">
              {% include "components/loading-spinner.html" %}
            </div>
          </div>
          <div id="appDomainAssessmentResultTable" class="mt-4"></div>
        </div>
      </div>
    {% endif %}
    {% if model.model_status == 'FINISHED' %}
      <!-- Single Gen Curve Panel -->
      <div class="collapse-arrow bg-base-200 collapse">
        <input type="checkbox" checked />
        <div class="collapse-title text-xl font-medium">
          Precision Recall Curve
        </div>
        <div class="collapse-content">
          <div class="flex justify-center">
            <div id="sg-chart"></div>
          </div>
        </div>
      </div>
      {% if model.multigen_eval %}
        <div class="collapse-arrow bg-base-200 collapse">
          <input type="checkbox" checked />
          <div class="collapse-title text-xl font-medium">
            Multi Gen Precision Recall Curve
          </div>
          <div class="collapse-content">
            <div class="flex justify-center">
              <div id="mg-chart"></div>
            </div>
          </div>
        </div>
      {% endif %}
    {% endif %}
  </div>

  {# prettier-ignore-start #}
    {# FIXME: This is a hack to get the precision recall curve data into the JavaScript code. #}
    <script>
        function handlePredictionResponse(data) {
            let stereo = data["stereo"]
            data = data["pred"]
            let res = ""
            if (stereo) {
                res += "<span class='alert alert-warning alert-soft'>Removed stereochemistry for prediction</span><br>"
            }
            res += "<table class='table table-zebra'>"
            res += "<thead>"
            res += "<th scope='col'>#</th>"

            const columns = ['products', 'image', 'probability', 'btrule']

            for (const col of columns) {
                res += "<th scope='col'>" + col + "</th>"
            }
            res += "</thead>"
            res += "<tbody>"
            let cnt = 1;
            for (const transformation in data) {
                res += "<tr>"
                res += "<th scope='row'>" + cnt + "</th>"
                res += "<th scope='row'>" + data[transformation]['products'][0].join(', ') + "</th>"
                res += "<th scope='row'>" + "<img width='400' src='{% url 'depict' %}?smiles=" + encodeURIComponent(data[transformation]['products'][0].join('.')) + "'></th>"
                res += "<th scope='row'>" + data[transformation]['probability'].toFixed(3) + "</th>"
                if (data[transformation]['btrule'] != null) {
                    res += "<th scope='row'>" + "<a href='" + data[transformation]['btrule']['url'] + "' class='link link-primary'>" + data[transformation]['btrule']['name'] + "</a>" + "</th>"
                } else {
                    res += "<th scope='row'>N/A</th>"
                }
                res += "</tr>"
                cnt += 1;
            }

            res += "</tbody>"
            res += "</table>"
            const resultTable = document.getElementById("predictResultTable");
            if (resultTable) {
                resultTable.innerHTML = res;
            }
        }

        function clear(divid) {
            const element = document.getElementById(divid);
            if (element) {
                element.classList.remove("alert", "alert-error");
                element.innerHTML = "";
            }
        }

        function makeChart(selector, data) {
            const x = ['Recall'];
            const y = ['Precision'];
            const thres = ['threshold'];

            function compare(a, b) {
                if (a.threshold < b.threshold)
                    return -1;
                else if (a.threshold > b.threshold)
                    return 1;
                else
                    return 0;
            }

            function getIndexForValue(data, val, val_name) {
                for (const idx in data) {
                    if (data[idx][val_name] == val) {
                        return idx;
                    }
                }
                return -1;
            }

            if (!data || data.length === 0) {
                console.warn('PR curve data is empty');
                return;
            }
            const dataLength = data.length;
            data.sort(compare);

            for (const idx in data) {
                const d = data[idx];
                x.push(d.recall);
                y.push(d.precision);
                thres.push(d.threshold);
            }
            const chart = c3.generate({
                bindto: selector,
                data: {
                    onclick: function (d, e) {
                        const idx = d.index;
                        const thresh = data[dataLength - idx - 1].threshold;
                    },
                    x: 'Recall',
                    y: 'Precision',
                    columns: [
                        x,
                        y,
                    ]
                },
                size: {
                    height: 400,
                    width: 480
                },
                axis: {
                    x: {
                        max: 1,
                        min: 0,
                        label: 'Recall',
                        padding: 0,
                        tick: {
                            fit: true,
                            values: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
                        }
                    },
                    y: {
                        max: 1,
                        min: 0,
                        label: 'Precision',
                        padding: 0,
                        tick: {
                            fit: true,
                            values: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
                        }
                    }
                },
                point: {
                    r: 4
                },
                tooltip: {
                    format: {
                        title: function (recall) {
                            const idx = getIndexForValue(data, recall, "recall");
                            if (idx != -1) {
                                return "Threshold: " + data[idx].threshold;
                            }
                            return "";
                        },
                        value: function (precision, ratio, id) {
                            return undefined;
                        }
                    }
                },
                zoom: {
                    enabled: true
                }
            });
        }

        function makeLoadingGif(selector, gifPath) {
            const element = document.querySelector(selector);
            if (element) {
                element.innerHTML = '<img src="' + gifPath + '" alt="Loading...">';
            }
        }

        document.addEventListener('DOMContentLoaded', function() {
            // Show actions button if there are actions
            const actionsButton = document.getElementById('actionsButton');
            const actionsList = actionsButton?.querySelector('ul');
            if (actionsList && actionsList.children.length > 0) {
                actionsButton?.classList.remove('hidden');
            }

            {% if model.model_status == 'FINISHED' %}
                // Precision Recall Curve
                makeChart('#sg-chart', {{ model.pr_curve|safe }});
                {% if model.multigen_eval %}
                    // Multi Gen Precision Recall Curve
                    makeChart('#mg-chart', {{ model.mg_pr_curve|safe }});
                {% endif %}
            {% endif %}

            // Predict button handler
            const predictButton = document.getElementById('predict-button');
            if (predictButton) {
                predictButton.addEventListener('click', function(e) {
                    e.preventDefault();

                    clear("predictResultTable");

                    const smilesInput = document.getElementById('smiles-to-predict');
                    const smiles = smilesInput ? smilesInput.value.trim() : '';

                    if (smiles === "") {
                        const resultTable = document.getElementById("predictResultTable");
                        if (resultTable) {
                            resultTable.classList.add("alert", "alert-error");
                            resultTable.innerHTML = "Please enter a SMILES string to predict!";
                        }
                        return;
                    }

                    const loadingEl = document.getElementById("predictLoading");
                    if (loadingEl) loadingEl.classList.remove("hidden");

                    const params = new URLSearchParams({
                        smiles: smiles,
                        classify: "ILikeCats!"
                    });

                    fetch('?' + params.toString(), {
                        method: 'GET',
                        headers: {
                            'X-CSRFToken': document.querySelector('[name=csrf-token]').content
                        }
                    })
                    .then(response => {
                        if (!response.ok) {
                            return response.json().then(err => { throw err; });
                        }
                        return response.json();
                    })
                    .then(data => {
                        const loadingEl = document.getElementById("predictLoading");
                        if (loadingEl) loadingEl.classList.add("hidden");
                        handlePredictionResponse(data);
                    })
                    .catch(error => {
                        const loadingEl = document.getElementById("predictLoading");
                        if (loadingEl) loadingEl.classList.add("hidden");
                        const resultTable = document.getElementById("predictResultTable");
                        if (resultTable) {
                            resultTable.classList.add("alert", "alert-error");
                            resultTable.innerHTML = error.error || "Error while processing response :/";
                        }
                    });
                });
            }

            // Assess button handler
            const assessButton = document.getElementById('assess-button');
            if (assessButton) {
                assessButton.addEventListener('click', function(e) {
                    e.preventDefault();

                    clear("appDomainAssessmentResultTable");

                    const smilesInput = document.getElementById('smiles-to-assess');
                    const smiles = smilesInput ? smilesInput.value.trim() : '';

                    if (smiles === "") {
                        const resultTable = document.getElementById("appDomainAssessmentResultTable");
                        if (resultTable) {
                            resultTable.classList.add("alert", "alert-error");
                            resultTable.innerHTML = "Please enter a SMILES string to predict!";
                        }
                        return;
                    }

                    const loadingEl = document.getElementById("appDomainLoading");
                    if (loadingEl) loadingEl.classList.remove("hidden");

                    const params = new URLSearchParams({
                        smiles: smiles,
                        "app-domain-assessment": "ILikeCats!"
                    });

                    fetch('?' + params.toString(), {
                        method: 'GET',
                        headers: {
                            'X-CSRFToken': document.querySelector('[name=csrf-token]').content
                        }
                    })
                    .then(response => {
                        if (!response.ok) {
                            return response.json().then(err => { throw err; });
                        }
                        return response.json();
                    })
                    .then(data => {
                        const loadingEl = document.getElementById("appDomainLoading");
                        if (loadingEl) loadingEl.classList.add("hidden");
                        if (typeof handleAssessmentResponse === 'function') {
                            handleAssessmentResponse("{% url 'depict' %}", data);
                        }
                        console.log(data);
                    })
                    .catch(error => {
                        const loadingEl = document.getElementById("appDomainLoading");
                        if (loadingEl) loadingEl.classList.add("hidden");
                        const resultTable = document.getElementById("appDomainAssessmentResultTable");
                        if (resultTable) {
                            resultTable.classList.add("alert", "alert-error");
                            resultTable.innerHTML = error.error || "Error while processing response :/";
                        }
                    });
                });
            }
        });
    </script>
    {# prettier-ignore-end #}
{% endblock content %}
