<script>
  import Icon from '$/client/components/Icon.svelte';
  import eachDayOfInterval from 'date-fns/eachDayOfInterval';
  import add from 'date-fns/add';
  import sub from 'date-fns/sub';
  import isSunday from 'date-fns/isSunday';
  import isSameDay from 'date-fns/isSameDay';
  import {createEventDispatcher} from "svelte";

  const dispatch = createEventDispatcher();
  let today = new Date();
  let year = today.getFullYear();
  let month = today.getMonth();
  let fom = new Date(year, month, 1);
  let display_date = fom.toLocaleDateString("en-US", { year: "numeric", month: "long" });

  /* Super American oriented, but future versions could use more of the Temporal API when it's more
  prevalent. */

  const first_sunday = () => {
    if(isSunday(fom)) {
      return fom; // awesome, it's a sunday
    } else {
      // looks like we have to find the previous sunday
      let prev = sub(fom, {days: 1});

      for(let i = 0; i < 7; i++) {
        if(isSunday(prev)) {
          return prev;
        } else {
          prev = sub(prev, {days: 1});
          return prev;
        }
      }
    }
  }

  let start = first_sunday(month);
  let end = add(start, { days: 35});

  const make_dates = () => {
    end = add(start, { days: (6 * 7) - 1});
    return eachDayOfInterval({start, end});
  }

  let dates = make_dates(month);

  const update_month = () => {
    year = fom.getFullYear();
    month = fom.getMonth();
    start = first_sunday();
    end = add(start, { days: (6 * 7) - 1});
    display_date = fom.toLocaleDateString("en-US", { year: "numeric", month: "long" });
    dates = make_dates();
  }

  const next_month = () => {
    fom = add(fom, {months: 1});
    update_month();
    dispatch("next", {fom});
  }

  const prev_month = () => {
    fom = sub(fom, {months: 1});
    update_month();
    dispatch("previous", {fom});
  }

</script>
<style>
  content {
    display: flex;
    flex-grow: 1;
  }

  calendar {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    grid-template-rows: auto;
    outline: 1px solid var(--color-accent);
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    width: 100%;
  }

  calendar day {
    background-color: var(--color-bg-secondary);
    font-weight: bold;
    text-align: center;
  }

  calendar month {
    grid-column: span 5;
    font-size: 1.5em;
    font-weight: bold;
    text-align: center;
    justify-content: space-evenly;
  }

  calendar span {
    text-align: center;
    display: inline-block;
  }

  calendar date {
    padding: 0.3rem;
    padding-left: 0.5rem;
  }

  calendar date:hover {
    background-color: var(--color-bg-secondary);
  }

  calendar date.not-month {
    color: var(--color-inactive);
  }

  calendar date.today {
    color: var(--color-bg);
    background-color: var(--color);
  }
</style>

<calendar>
  <span on:click={ () => prev_month(-1) }><Icon name="arrow-left-circle" size="1.5em" /></span>
  <month>
    { display_date }
  </month>
  <span on:click={ () => next_month(1) }><Icon name="arrow-right-circle" size="1.5em" /></span>

  <day>Sun</day><day>Mon</day><day>Tue</day><day>Wed</day><day>Thu</day><day>Fri</day><day>Sat</day>
  {#each dates as date}
    <date class:today={ isSameDay(date, today) } class:not-month={ date.getMonth() !== fom.getMonth()} on:click={ () => dispatch("select", date) }>{date.getDate()}</date>
  {/each}
</calendar>

