<script lang="ts">
  import LogEntry from "../components/LogEntry.svelte";
  import type { LogFilter, LogResult } from "../models/log";
  import logStore from "../stores/logs";
  import { addDays, formatWeekdayDate, startOfDay } from "../utils/time";
  import { allOffsets, RelativeDateRange } from "../utils/date-range";
  import EmptyList from "../components/EmptyList.svelte";
  import RefreshSelection from "../components/RefreshSelection.svelte";
  import DateRangeSelect from "../components/DateRangeSelect.svelte";
  import EveryMinute from "../components/EveryMinute.svelte";
  import ProjectGroupSelect from "../components/ProjectGroupSelect.svelte";
  import ProjectSelect from "../components/ProjectSelect.svelte";
  import ItemSelect from "../components/ItemSelect.svelte";
  import projectStore from "../stores/project";
  import projectGroupStore from "../stores/projectGroup";
  import ItemProgress from "../components/ItemProgress.svelte";
  
  const lsValue = localStorage.getItem("sl2.logspage.range")

  let groupedLogs: {day: Date, text: string, logs: LogResult[]}[] = [];
  let range = allOffsets.find(o => o.name === lsValue) || new RelativeDateRange(-7, "day");
  let now = new Date();
  let error = "";
  let emptyMessage = "Loading...";

  let min: Date;
  let max: Date;

  let projectGroupId = localStorage.getItem("sl2.logspage.project_group_id") || "";
  let projectId = localStorage.getItem("sl2.logspage.project_id") || "";
  let itemId = localStorage.getItem("sl2.logspage.item_id") || "";

  $: [min, max] = range.calculate(now);

  $: localStorage.setItem("sl2.logspage.range", range.name);
  $: localStorage.setItem("sl2.logspage.project_group_id", projectGroupId);
  $: localStorage.setItem("sl2.logspage.project_id", projectId);
  $: localStorage.setItem("sl2.logspage.item_id", itemId);

  $: {
    if ($projectStore.stale && !$projectStore.loading) {
      projectStore.load({});
    }
  }

  $: {
    if ($projectGroupStore.stale && !$projectGroupStore.loading) {
      projectGroupStore.load();
    }
  }

  $: {
    error = "";

    if (!Number.isNaN(min.getTime()) && !Number.isNaN(max.getTime())) {
      if (min.getTime() < max.getTime()) {
        if (!$logStore.loading) {
          const filter: LogFilter = {
            minTime: min, 
            maxTime: max,
            itemIds: itemId ? itemId.split(",") : void(0),
            projectIds: projectId ? [projectId] : void(0),
            projectGroupIds: (!projectId && projectGroupId) ? [projectGroupId] : void(0),
          }

          if ($logStore.stale || JSON.stringify(filter) !== JSON.stringify($logStore.filter)) {
            logStore.load(filter);
          }
        }
      } else {
        error = "Time only goes one way in this universe, you should respect that."
      }
    } else {
      error = "The dates must be valid."
    }
  }

  $: {
    if (!$logStore.loading && !$logStore.stale) {
      emptyMessage = `No matching logs between ${formatWeekdayDate(min)} and ${formatWeekdayDate(max)}.`;
    } else {
      emptyMessage = "Loading...";
    }
  }

  $: {
    if (!$logStore.loading) {
      groupedLogs = [];

      if ($logStore.logs.length > 0) {

        const today = new Date();
        const tomorrow = addDays(today, 1);
        const yesterday = addDays(today, -1);

        let current = new Date($logStore.logs[0].loggedTime);

        let remainingLogs = $logStore.logs;

        while (remainingLogs.length > 0) {
          const currentDay = startOfDay(current);

          const currentLogs: LogResult[] = [];
          for (const log of remainingLogs) {
            if (Date.parse(log.loggedTime) >= currentDay.getTime()) {
              currentLogs.push(log);
            } else {
              break;
            }
          }

          if (currentLogs.length > 0) {
            remainingLogs = remainingLogs.slice(currentLogs.length);

            let text = formatWeekdayDate(current);
            if (current.getTime() === tomorrow.getTime()) {
              text = "Tomorrow";
            } else if (current.getTime() === today.getTime()) {
              text = "Today";
            } else if (current.getTime() === yesterday.getTime()) {
              text = "Yesterday";
            }
            
            groupedLogs.push({day: current, text, logs: currentLogs});
          }

          current = addDays(current, -1);
        }
      }
    }
  }
</script>

<div class="page">
  <DateRangeSelect label="Time Filter" noFuture styled bind:value={range} />
  <div class="extra-filters">
    <div class="filter-group">
      <label for="projectGroup">Project Group</label>
      <ProjectGroupSelect name="projectGroup" optional bind:value={projectGroupId} placeholder="Any" />
    </div>
    <div class="filter-group">
      <label for="project">Project</label>
      <ProjectSelect name="project" disabled={projectGroupId === ""} optional bind:value={projectId} groupId={projectGroupId} forceGroup placeholder="Any" />
    </div>
    <div class="filter-group">
      <label for="item">Item</label>
      <ItemSelect name="item" optional bind:value={itemId} enableWholeGroup placeholder="Any" />
    </div>
  </div>
  <div class="error">{error}</div>
  <ItemProgress logs={$logStore.logs} centered />
  <div class="log-list" class:loading={$logStore.loading}>
    {#each groupedLogs as logGroup (logGroup.day.getTime())}
      <h2>{logGroup.text}</h2>
      <ItemProgress logs={logGroup.logs} centered />
      {#each logGroup.logs as log (log.id)}
        <LogEntry log={log} />
      {/each}
    {/each}
    {#if groupedLogs.length === 0}
      <EmptyList icon="list" text={emptyMessage} />
    {/if}
  </div>
</div>
<RefreshSelection />
<EveryMinute bind:now={now} />

<style>
  div.error {
    color: #ff4545;
    text-align: center;
  }
  div.error:empty {
    display: none;
  }

  div.page {
    display: block;
    margin: auto;
    max-width: 100%;
    width: 640px;
    margin-top: 0;
    box-sizing: border-box;
  }

  div.log-list.loading {
    opacity: 0.75;
  }

  div.extra-filters {
    display: flex;
    flex-direction: row;
  }
  div.filter-group {
    flex: 1;
    padding: 0 0.5em;
    margin: 0 auto;
  }
  div.filter-group label {
    line-height: 1.5em;
  }
  div.filter-group :global(select) {
    width: 100%;
    margin-bottom: 0.5em;

    background: #222;
    color: #777;
    border: none;
    outline: none;
    resize: vertical;
  }
  div.filter-group :global(select:focus) {
    background: #191919;
    color: #CCC;
    border: none;
    outline: none;
  }

  h2 {
    font-size: 1.5em;
    font-weight: 100;
    text-align: center;
    margin: 0;
    margin-top: 1em;
  }

  @media screen and (max-width: 900px) {
    div.extra-filters {
      flex-direction: column;
    }

    div.filter-group {
      width: 90%;
    }
  }

</style>