@using Server.Models
@using System.Web
@using Server.Services
@inject LocalizationService T
@model HomeIndexViewModel
@{
    ViewData["Title"] = "Home Page";
    int i = 0;
    Dictionary<int, string> domains = [];
    Model.Searchdomains.ForEach(domain =>
    {
        domains[i++] = domain;
    });
}

<div class="container-fluid mt-4">
  <h1 class="visually-hidden">embeddingsearch</h1>
  <div class="row">

    <!-- Sidebar -->
    <div class="col-md-4 sidebar" role="complementary">
      <div class="card">
        <div class="card-body p-2">
          <h2 class="visually-hidden">@T["Searchdomain selection"]</h2>
          <ul class="list-group list-group-flush mb-2" style="max-height: 60vh; overflow-y: auto;">
            @foreach (var domain in domains)
            {
                <li id="sidebar_domain_@(domain.Key)" class="domain-item list-group-item list-group-item-action text-nowrap" style="width: max-content" title="@domain.Value" onclick="selectDomain(@(domain.Key))">
                    @domain.Value
                </li>
            }
          </ul>
          <button class="btn btn-primary w-100">Add</button>
        </div>
      </div>
    </div>

    <!-- Main Content -->
    <div class="col col-md-8" role="main">

      <div class="card section-card">
        <div class="card-body">
          <h2 class="visually-hidden">@T["Searchdomain information and settings"]</h2>

          <!-- Header -->
          <div class="d-flex justify-content-between align-items-center mb-3">
            <h3 class="mb-0 text-nowrap overflow-auto">Searchdomain</h3>
            <div class="col-md-3 text-end w-auto">
              <button id="searchdomainRename" class="btn btn-warning btn-sm me-2">Rename</button>
              <button id="searchdomainDelete" class="btn btn-danger btn-sm">Delete</button>
            </div>
          </div>

          <!-- Settings -->
          <div class="row align-items-center mb-3">
            <label class="form-label">Settings</label>
            <div class="col-md-6">
              <input type="checkbox" class="form-check-input" id="searchdomainConfigCacheReconciliation" />
              <label class="form-check-label" for="searchdomainConfigCacheReconciliation">@T["Cache reconsiliation"]</label>
            </div>
            <div class="col-md-2 mt-3 mt-md-0">
              <button class="btn btn-warning w-100" id="searchdomainConfigUpdate">@T["Update"]</button>
            </div>
          </div>

          <!-- Cache -->
          <div class="d-flex align-items-center mb-4">
            <div class="me-3">
              <strong>Cache utilization:</strong> 2.47MiB
            </div>
            <button class="btn btn-primary btn-sm">Reset</button>
          </div>

          <!-- Recent Queries -->
          <div class="card section-card mb-4">
            <div class="card-body">
              <div class="d-flex justify-content-between align-items-center mb-2">
                <strong>Recent queries</strong>
                <input
                  type="text"
                  class="form-control form-control-sm w-25"
                  placeholder="filter"
                />
              </div>
              <div class="spinner d-none"></div>
              <table id="queriesTable" class="table table-striped" style="max-height: 60vh; overflow-y: auto; display: block;">
                <thead>
                  <tr>
                    <th class="visually-hidden">Name</th>
                    <th class="visually-hidden">Action</th>
                  </tr>
                </thead>
                <tbody>
                </tbody>
              </table>
            </div>
          </div>

          <!-- Entities -->
          <div class="card section-card">
            <div class="card-body">
              <div class="d-flex justify-content-between align-items-center mb-2">
                <strong>Entities</strong>
                <input
                  id="entitiesFilter"
                  type="text"
                  class="form-control form-control-sm w-25"
                  placeholder="filter"
                />
              </div>
              <div class="spinner d-none"></div>
              <table id="entitiesTable" class="table table-striped" style="max-height: 60vh; overflow-y: auto; display: block;">
                <thead>
                  <tr>
                    <th class="visually-hidden">Name</th>
                    <th class="visually-hidden">Action</th>
                  </tr>
                </thead>
                <tbody>
                </tbody>
              </table>
            </div>
          </div>

        </div>
      </div>

    </div>
  </div>
</div>

<!-- Entity Details Modal -->
<div class="modal fade" id="entityDetailsModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-lg modal-dialog-scrollable">
    <div class="modal-content">
      <div class="modal-header bg-info">
        <h2 class="modal-title" id="entityDetailsTitle">@T["Entity Details"]</h2>
        <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
      </div>

      <div class="modal-body">
        <!-- Attributes -->
        <h3 class="fs-4">@T["Attributes"]</h3>
        <table class="table table-sm table-bordered mb-4">
          <thead>
            <tr>
              <th>@T["Key"]</th>
              <th>@T["Value"]</th>
            </tr>
          </thead>
          <tbody id="entityAttributesBody">
          </tbody>
        </table>

        <!-- Datapoints -->
        <h3 class="fs-4">@T["Datapoints"]</h3>
        <table class="table table-sm table-striped">
          <thead>
            <tr>
              <th>@T["Name"]</th>
              <th>@T["ProbMethod"]</th>
              <th>@T["SimilarityMethod"]</th>
            </tr>
          </thead>
          <tbody id="entityDatapointsBody">
          </tbody>
        </table>
      </div>

      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
          @T["Close"]
        </button>
      </div>
    </div>
  </div>
</div>

<!-- Query Details Modal -->
<div class="modal fade" id="queryDetailsModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-xl modal-dialog-scrollable">
    <div class="modal-content">

      <div class="modal-header">
        <h2 class="modal-title" id="queryDetailsTitle">Query Details</h2>
        <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
      </div>

      <div class="modal-body">

        <!-- Access times -->
        <h3>Access times</h3>
        <ul id="queryAccessTimes" class="list-group mb-4"></ul>

        <!-- Results -->
        <h3>Results</h3>
        <table class="table table-sm table-striped">
          <thead>
            <tr>
              <th>Score</th>
              <th>Name</th>
            </tr>
          </thead>
          <tbody id="queryResultsBody"></tbody>
        </table>

      </div>

      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
          Close
        </button>
      </div>

    </div>
  </div>
</div>

<!-- Rename searchdomain Modal -->
<div class="modal fade" id="renameSearchdomainModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-m modal-dialog-scrollable">
    <div class="modal-content">

      <div class="modal-header bg-warning">
        <h2 class="modal-title" id="renameSearchdomainTitle">@T["Rename searchdomain"]</h2>
        <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
      </div>

      <div class="modal-body">
        <!-- New name -->
        <div class="mb-3">
          <label for="renameSearchdomainNewName" class="form-label">New name</label>
          <input type="text" class="form-control" id="renameSearchdomainNewName" />
        </div>
      </div>

      <div class="modal-footer">
        <button type="button" class="btn btn-warning" onclick="renameSearchdomain(getSelectedDomainKey(), document.getElementById('renameSearchdomainNewName').value)" data-bs-dismiss="modal">
          Rename
        </button>
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
          Close
        </button>
      </div>
    </div>
  </div>
</div>

<!-- Delete searchdomain Modal -->
<div class="modal fade" id="deleteSearchdomainModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-m modal-dialog-scrollable">
    <div class="modal-content">

      <div class="modal-header bg-danger text-white">
        <h2 class="modal-title" id="deleteSearchdomainTitle">@T["Delete searchdomain"]</h2>
        <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
      </div>

      <div class="modal-body">
        <p>@T["Are you sure you want to delete this searchdomain? This action cannot be undone."]</p>
      </div>

      <div class="modal-footer">
        <button type="button" id="searchdomainConfirmDelete" class="btn btn-danger" data-bs-dismiss="modal">
          Delete
        </button>
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
          Close
        </button>
      </div>

    </div>
  </div>
</div>


<script>
    var domains = JSON.parse('@Html.Raw(System.Text.Json.JsonSerializer.Serialize(domains))');
    var entities = null;
    var queries = null;

    document.addEventListener('DOMContentLoaded', () => {
        const filterInput = document.getElementById('entitiesFilter');

        filterInput.addEventListener('input', () => {
            populateEntitiesTable(filterInput.value);
        });
    });

    document.addEventListener('DOMContentLoaded', () => {
        const entitiesFilter = document.getElementById('entitiesFilter');
        entitiesFilter.addEventListener('input', () => {
            populateEntitiesTable(entitiesFilter.value);
        });

        const queriesFilter = document.querySelector(
            '#queriesTable'
        ).closest('.card-body').querySelector('input');

        queriesFilter.addEventListener('input', () => {
            populateQueriesTable(queriesFilter.value);
        });
        selectDomain(0);

        document
            .getElementById('searchdomainRename')
            .addEventListener('click', () => {
                const modal = new bootstrap.Modal(
                    document.getElementById('renameSearchdomainModal')
                );
                // Fill in searchdomain current name
                const domainKey = getSelectedDomainKey();
                document.getElementById(
                    'renameSearchdomainNewName'
                ).value = domains[domainKey];
                modal.show();
            });
        document
            .getElementById('searchdomainDelete')
            .addEventListener('click', () => {
                const modal = new bootstrap.Modal(
                    document.getElementById('deleteSearchdomainModal')
                );
                modal.show();
            });
        document
            .getElementById('searchdomainConfirmDelete')
            .addEventListener('click', () => {
                const domainKey = getSelectedDomainKey();
                deleteSearchdomain(domainKey);
                selectDomain(0);
            });
        document
            .getElementById('searchdomainConfigUpdate')
            .addEventListener('click', () => {
                const domainKey = getSelectedDomainKey();
                const cacheReconciliation = document.getElementById('searchdomainConfigCacheReconciliation').checked;
                updateSearchdomainConfig(domainKey, { CacheReconciliation: cacheReconciliation});
            });
    });

    function deleteSearchdomain(domainKey) {
        // Implement delete logic here
        fetch(`/Searchdomain/Delete?searchdomain=${encodeURI(domains[domainKey])}`, {
            method: 'GET'
        }).then(response => {
            if (response.ok) {
                // TODO add toast
                // Remove from sidebar
                var domainItem = document.getElementById('sidebar_domain_' + domainKey);
                domainItem.remove();
                console.log('Searchdomain deleted successfully');
            } else {
                // TODO add toast
                console.error('Failed to delete searchdomain');
            }
        }).catch(error => {
            console.error('Error deleting searchdomain:', error);
        });
    }

    function renameSearchdomain(domainKey, newName) {
        // Implement rename logic here
        fetch(`/Searchdomain/Update?searchdomain=${encodeURI(domains[domainKey])}&newName=${newName}`, {
            method: 'GET'
        }).then(response => {
            if (response.ok) {
                // TODO add toast
                // Update sidebar and header name
                var domainItem = document.getElementById('sidebar_domain_' + domainKey);
                domainItem.innerText = newName;
                document.querySelector('.section-card h3').innerText = newName;
                domains[domainKey] = newName;

                console.log('Searchdomain renamed successfully');
            } else {
                // TODO add toast
                console.error('Failed to rename searchdomain');
            }
        }).catch(error => {
            console.error('Error renaming searchdomain:', error);
        });
    }

    function updateSearchdomainConfig(domainKey, newSettings) {
        // Implement update logic here
        fetch(`/Searchdomain/UpdateSettings?searchdomain=${encodeURIComponent(domains[domainKey])}`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(newSettings)
        }).then(response => {
            if (response.ok) {
                // TODO add toast
                console.log('Searchdomain settings updated successfully');
            } else {
                // TODO add toast
                console.error('Failed to update searchdomain settings');
            }
        }).catch(error => {
            console.error('Error updating searchdomain settings:', error);
        });
    }

    function getSelectedDomainKey() {
        return document.querySelector('.domain-item.active').id.split("_")[2] - 0;
    }

    function getSearchdomainConfig(domainKey) {
        return fetch(`/Searchdomain/GetSettings?searchdomain=${encodeURIComponent(domains[domainKey])}`)
            .then(r => r.json());
    }

    function selectDomain(domainKey) {
        document.querySelectorAll('.domain-item').forEach(item => {
            item.classList.remove('active');
        });

        var selectedItem = document.getElementById('sidebar_domain_' + domainKey);
        selectedItem.classList.add('active');

        var domainName = domains[domainKey];
        document.querySelector('.section-card h3').innerText = domainName;

        let searchdomainConfigPromise = getSearchdomainConfig(getSelectedDomainKey());
        let configElementCacheReconsiliation = document.getElementById('searchdomainConfigCacheReconciliation');

        /* ---------- ENTITIES ---------- */
        let entitiesUrl = `/Entity/List?searchdomain=${encodeURIComponent(domainName)}&returnEmbeddings=false`;
        let entitiesCard = document.querySelector("#entitiesTable").parentElement;
        clearEntitiesTable();
        showEntitiesLoading(entitiesCard);

        fetch(entitiesUrl)
            .then(r => r.json())
            .then(data => {
                entities = data.Results;
                populateEntitiesTable();
                hideEntitiesLoading(entitiesCard);
            })
            .catch(err => {
                console.error(err);
                flagSearchdomainAsErroneous(domainKey);
                hideEntitiesLoading(entitiesCard);
            });

        /* ---------- QUERIES ---------- */
        let queriesUrl = `/Searchdomain/GetSearches?searchdomain=${encodeURIComponent(domainName)}`;
        let queriesCard = document.querySelector("#queriesTable").parentElement;
        clearQueriesTable();
        showQueriesLoading(queriesCard);

        fetch(queriesUrl)
            .then(r => r.json())
            .then(data => {
                queries = Object.entries(data.Searches).map(key => ({"Name": key[0], "AccessDateTimes": key[1].AccessDateTimes, "Results": key[1].Results}));
                populateQueriesTable();
                hideQueriesLoading(queriesCard);
            })
            .catch(err => {
                console.error('Error fetching queries:', err);
                hideQueriesLoading(queriesCard);
            });

        searchdomainConfigPromise.then(searchdomainConfig => {
            if (searchdomainConfig != null && searchdomainConfig.Settings != null)
            {
                console.log(searchdomainConfig);
                configElementCacheReconsiliation.checked = searchdomainConfig.Settings.CacheReconciliation;
                configElementCacheReconsiliation.disabled = false;
            } else {
                //configElement.value = 'Error fetching searchdomain config';
                configElementCacheReconsiliation.disabled = true;
                // TODO add toast
                console.error('Failed to fetch searchdomain config');
            }
        });
    }

    function clearEntitiesTable() {
        var tableBody = document.querySelector('#entitiesTable tbody');
        tableBody.innerHTML = '';
    }

    function clearQueriesTable() {
        document.querySelector('#queriesTable tbody').innerHTML = '';
    }

    function populateEntitiesTable(filterText = '') {
        if (!entities) return;

        var tableBody = document.querySelector('#entitiesTable tbody');
        tableBody.innerHTML = '';

        const normalizedFilter = filterText.toLowerCase();

        let isFirstEntity = true;
        entities
        .filter(e => e.Name.toLowerCase().includes(normalizedFilter))
        .forEach(entity => {
            var row = document.createElement('tr');

            var nameCell = document.createElement('td');
            nameCell.textContent = entity.Name;
            if (isFirstEntity) {
              nameCell.classList.add('w-100'); // Otherwise the table doesn't use the full width
              isFirstEntity = false;
            }
            row.appendChild(nameCell);

            var actionCell = document.createElement('td');
            var detailsButton = document.createElement('button');
            detailsButton.className = 'btn btn-info btn-sm';
            detailsButton.textContent = 'Details';
            detailsButton.setAttribute("data-index", entities.findIndex(en => en == entity));
            detailsButton.addEventListener('click', () => {
              showEntityDetails(entity);
            });

            actionCell.appendChild(detailsButton);
            row.appendChild(actionCell);

            tableBody.appendChild(row);
        });
    }

    function populateQueriesTable(filterText = '') {
        if (!queries) return;


        const tbody = document.querySelector('#queriesTable tbody');
        tbody.innerHTML = '';

        const normalizedFilter = filterText.toLowerCase();

        queries
            .filter(q => q.Name?.toLowerCase().includes(normalizedFilter))
            .forEach(query => {
                const row = document.createElement('tr');

                const nameCell = document.createElement('td');
                nameCell.textContent = query.Name;
                nameCell.classList.add('col-md-12');
                row.appendChild(nameCell);

                const actionCell = document.createElement('td');
                const btn = document.createElement('button');
                btn.className = 'btn btn-sm btn-primary';
                btn.textContent = '@T["Details"]';
                btn.addEventListener('click', () => {
                    showQueryDetails(query);
                });

                actionCell.appendChild(btn);
                row.appendChild(actionCell);

                tbody.appendChild(row);
            });



    }

    function flagSearchdomainAsErroneous(domainKey) {
      var domainItem = document.getElementById('sidebar_domain_' + domainKey);
      domainItem.classList.add('list-group-item-danger');
    }

    function showEntitiesLoading(element = null) {
      if (element == null) element = document;
      element.querySelector('.spinner').classList.remove('d-none');
    }

    function hideEntitiesLoading(element = null) {
      if (element == null) element = document;
      element.querySelector('.spinner').classList.add('d-none');
    }

    function showQueriesLoading(element = null) {
        if (!element) element = document;
        element.querySelector('.spinner').classList.remove('d-none');
    }

    function hideQueriesLoading(element = null) {
        if (!element) element = document;
        element.querySelector('.spinner').classList.add('d-none');
    }

    function showEntityDetails(entity) {
      // Title
      document.getElementById('entityDetailsTitle').innerText = entity.Name;

      // Attributes
      const attrBody = document.getElementById('entityAttributesBody');
      attrBody.innerHTML = '';

      const attributes = entity.Attributes || {};
      const attrKeys = Object.keys(attributes);

      if (attrKeys.length === 0) {
          attrBody.innerHTML = `
              <tr>
                <td colspan="2" class="text-muted text-center">No attributes</td>
              </tr>`;
      } else {
          attrKeys.forEach(key => {
              const row = document.createElement('tr');
              attributeKV = attributes[key];
              row.innerHTML = `
                <td>${attributeKV["Name"]}</td>
                <td>${attributeKV["Value"]}</td>
              `;
              attrBody.appendChild(row);
          });
      }

      // Datapoints
      const dpBody = document.getElementById('entityDatapointsBody');
      dpBody.innerHTML = '';

      (entity.Datapoints || []).forEach(dp => {
          const row = document.createElement('tr');
          row.innerHTML = `
            <td>${dp.Name}</td>
            <td>${dp.ProbMethod}</td>
            <td>${dp.SimilarityMethod}</td>
          `;
          dpBody.appendChild(row);
      });

      // Show modal
      const modal = new bootstrap.Modal(
          document.getElementById('entityDetailsModal')
      );
      modal.show();
    }

    function showQueryDetails(query) {
        // Title
        document.getElementById('queryDetailsTitle').innerText =
            `Query: ${query.Name}`;

        /* ---------- Access times ---------- */
        const accessList = document.getElementById('queryAccessTimes');
        accessList.innerHTML = '';

        if (!query.AccessDateTimes || query.AccessDateTimes.length === 0) {
            accessList.innerHTML = `
                <li class="list-group-item text-muted text-center">
                    No access times
                </li>`;
        } else {
            query.AccessDateTimes.forEach(dt => {
                const li = document.createElement('li');
                li.className = 'list-group-item';
                li.textContent = new Date(dt).toLocaleString();
                accessList.appendChild(li);
            });
        }

        /* ---------- Results ---------- */
        const resultsBody = document.getElementById('queryResultsBody');
        resultsBody.innerHTML = '';

        if (!query.Results || query.Results.length === 0) {
            resultsBody.innerHTML = `
                <tr>
                  <td colspan="2" class="text-muted text-center">
                    No results
                  </td>
                </tr>`;
        } else {
            query.Results.forEach(r => {
                const row = document.createElement('tr');
                row.innerHTML = `
                    <td>${r.Score.toFixed(4)}</td>
                    <td class="text-break">${r.Name}</td>
                `;
                resultsBody.appendChild(row);
            });
        }

        // Show modal
        const modal = new bootstrap.Modal(
            document.getElementById('queryDetailsModal')
        );
        modal.show();
    }

</script>