<script lang="ts">
  import { getStores } from "$app/stores";

  import { sl3 } from "$lib/clients/sl3";
  import Modal from "$lib/components/common/Modal.svelte";
  import ModalBody from "$lib/components/common/ModalBody.svelte";
  import { getModalContext } from "$lib/components/contexts/ModalContext.svelte";
  import { getProjectContext } from "$lib/components/contexts/ProjectContext.svelte";
  import { getScopeContext } from "$lib/components/contexts/ScopeContext.svelte";
    import ProjectSelect from "$lib/components/controls/ProjectSelect.svelte";
  import StatInput from "$lib/components/controls/StatInput.svelte";
  import StatusSelect from "$lib/components/controls/StatusSelect.svelte";
    import TagInput from "$lib/components/controls/TagInput.svelte";
  import Checkbox from "$lib/components/layout/Checkbox.svelte";
  import type { ProjectEntry, Requirement, RequirementInput } from "$lib/models/project";
  import Status from "$lib/models/status";
  import { statDiff } from "$lib/utils/stat";

  const {currentModal, closeModal} = getModalContext();
  const {scope} = getScopeContext();
  const {project, reloadProject} = getProjectContext();
  const {page} = getStores();

  let requirement: RequirementInput
  let projectId: number
  let requirementId: number
  let oldStats: RequirementInput["stats"]
  let showAggregateRequired: boolean
  let oldTags: string[]

  let error: string
  let loading: boolean
  let show: boolean
  let op: "Create" | "Edit" | "Delete"

  $: switch ($currentModal.name) {
    case "requirement.create":
      initCreate($currentModal.project);
      op = "Create";
      break;

    case "requirement.edit":
      initEdit($currentModal.requirement, $project);
      op = "Edit";
      break;

    default:
      loading = false;
      error = null;
      show = false;
  }

  $: showAggregateRequired = requirement?.stats?.find(s => s.required > 0) == null;

  function initCreate(project: ProjectEntry) {
    requirement = {
      name: "",
      description: "",
      stats: [],
      status: Status.Available,
      isCoarse: false,
      aggregateRequired: 0,
      tags: [],
      projectId: project.id,
    }

    projectId = project.id;
    show = true;
  }

  function initEdit(current: Requirement, project: ProjectEntry) {
    requirement = {
      name: current.name,
      description: current.description,
      status: current.status,
      stats: current.stats.map(s => ({acquired: s.acquired, required: s.required, statId: s.id})),
      isCoarse: current.isCoarse,
      aggregateRequired: current.aggregateRequired,
      tags: [...current.tags],
      projectId: project.id,
    }

    oldTags = [...current.tags];
    oldStats = [...requirement.stats];
    projectId = project.id;
    requirementId = current.id;
    show = true;
  }

  async function submit() {
    error = null;
    loading = true;

    if (requirement.stats.find(s => s.required > 0)) {
      requirement.aggregateRequired = 0;
    }

    try {
      switch (op) {
        case "Create":
          await sl3(fetch).createRequirement($scope.id, projectId, requirement);
          break;
        case "Edit":
          const submission: Partial<RequirementInput> = {
            ...requirement,
            stats: statDiff(oldStats, requirement.stats, -1),
            addTags: requirement.tags.filter(t => !oldTags.includes(t)),
            removeTags: oldTags.filter(t => !requirement.tags.includes(t)),
            projectId: requirement.projectId !== projectId ? requirement.projectId : void(0),
          };

          await sl3(fetch).updateRequirement($scope.id, projectId, requirementId, submission);
          break;
      }
    
      // Wait for project to reload
      await reloadProject();

      closeModal();
    } catch(err) {
      if (err.statusCode != null) {
        error = err.statusMessage;
      } else {
        error = err
      }

    } finally {
      loading = false;
    }
  }
</script>

<form on:submit|preventDefault={submit}>
  <Modal show={show} wide closable verb={op} noun="Requirement" disabled={loading} error={error}>
    <ModalBody>
      <label for="name">Name</label>
      <input name="name" type="text" bind:value={requirement.name} />
      <label for="description">Description</label>
      <textarea name="description" bind:value={requirement.description} />
      {#if showAggregateRequired}
        <label for="aggregateRequired">Aggregate Required (Zero for old behavior)</label>
        <input name="aggregateRequired" type="number" bind:value={requirement.aggregateRequired} />
      {/if}
      <TagInput bind:value={requirement.tags} />
    </ModalBody>
    <ModalBody>
      <label for="req">Project Requirement</label>
      <ProjectSelect disabled={op === "Create"} bind:value={requirement.projectId} />
      <label for="stats">Status</label>
      <StatusSelect bind:status={requirement.status} />
      <label for="stats">Stats</label>
      <StatInput showRequired bind:value={requirement.stats} />
      <Checkbox bind:checked={requirement.isCoarse} label="Hide 0-requirement stats." />
    </ModalBody>
  </Modal>
</form>