<script>
  import Reason from '$lib/raw-fetchers/reason.svelte';

  export let services;
  export let click;

  async function generateServiceData(service) {
    const timeDetails = parseTimes(service);
    let serviceData = {
      from: await parseLocation(service.origin),
      to: await parseLocation(service.destination),
      length: await getTrainLength(service),
      platform: await parsePlatform(service?.platform || 'undefined'),
      platformHidden: service?.platformIsHidden === 'true',
      schArr: timeDetails.schArr,
      expArr: timeDetails.expArr,
      schDep: timeDetails.schDep,
      expDep: timeDetails.expDep,
      isEarlyArr: timeDetails.earArr,
      isLateArr: timeDetails.delArr,
      isEarlyDep: timeDetails.earDep,
      isLateDep: timeDetails.delDep,
      isCancelled: Boolean(service?.isCancelled),
      canArr: timeDetails.canArr,
      canDep: timeDetails.canDep,
      isDelayed: service?.arrivalType === 'Delayed',
      isArrDelayed: service?.arrivalType === 'Delayed',
      isDepDelayed: service?.departureType === 'Delayed',
      isNonPublic: service?.isPassengerService === 'false' ? true : false
    };
    return serviceData;
  }

  async function getTrainLength(service) {
    if (service?.length) {
      return parseInt(service?.length);
    } else if (service?.formation?.coaches) {
      return service.formation.coaches.coach.length;
    }
    return null;
  }

  async function parseLocation(location) {
    if (!Array.isArray(location.location)) {
      return location.location?.tiploc;
    }
    let locations = [];
    for (const singleLocation of location?.location) {
      locations.push(singleLocation?.tiploc);
    }
    return locations.join(' & ');
  }

  function parseTimes(service) {
    let schArr = new Date(service?.sta);
    let expArr = new Date(service?.eta || service?.ata);
    let schDep = new Date(service?.std);
    let expDep = new Date(service?.etd || service?.atd);
    let isEarlyArr = false,
      isDelayedArr = false,
      isArr = false,
      canArr = false;
    let isEarlyDep = false,
      isDelayedDep = false,
      isDep = false,
      canDep = false;
    const timeDifferenceThreshold = 60 * 1000; // 60 seconds in milliseconds
    if (expArr - schArr < -timeDifferenceThreshold) {
      isEarlyArr = true;
      isArr = true;
    } else if (expArr - schArr > timeDifferenceThreshold) {
      isDelayedArr = true;
      isArr = true;
    }

    if (expDep - schDep < -timeDifferenceThreshold) {
      isEarlyDep = true;
      isDep = true;
    } else if (expDep - schDep > timeDifferenceThreshold) {
      isDelayedDep = true;
      isDep = true;
    }
    let parsedExpArr;
    if (expArr instanceof Date && !isNaN(expArr)) {
      if (!isEarlyArr && !isDelayedArr) {
        parsedExpArr = 'RT';
      } else {
        parsedExpArr = parseIndividualTime(expArr);
      }
    } else if (service.isCancelled === 'true') {
      parsedExpArr = 'CANC';
      canArr = true;
    } else {
      parsedExpArr = '-';
    }

    let parsedExpDep;
    if (expDep instanceof Date && !isNaN(expDep)) {
      if (!isEarlyDep && !isDelayedDep) {
        parsedExpDep = 'RT';
      } else {
        parsedExpDep = parseIndividualTime(expDep);
      }
    } else if (service.isCancelled === 'true') {
      parsedExpDep = 'CANC';
      canDep = true;
    } else {
      parsedExpDep = '-';
    }
    return {
      schArr: parseIndividualTime(schArr),
      expArr: parsedExpArr,
      schDep: parseIndividualTime(schDep),
      expDep: parsedExpDep,
      earArr: isEarlyArr,
      delArr: isDelayedArr,
      earDep: isEarlyDep,
      delDep: isDelayedDep,
      canArr: canArr,
      canDep: canDep
    };
  }

  function parseIndividualTime(input) {
    const dt = new Date(input);
    const output = dt.toLocaleTimeString([], {
      hour: '2-digit',
      minute: '2-digit'
    });
    if (output !== 'Invalid Date') {
      return output;
    }
    return '-';
  }

  async function parsePlatform(platform) {
    if (!platform) {
      return '-';
    }
    if (platform === 'TBC' || platform == 'undefined') {
      return '-';
    }
    return {
      number: platform
    };
  }

  function detail(event, rid, uid, tid) {
    const target = event.target;
    click(rid, uid, tid);
  }
</script>

<p class="smallScreen">Your display is too small to view this data</p>
<table>
  <tr>
    <th class="id">ID</th>
    <th class="from">From</th>
    <th class="to">To</th>
    <th class="plat">Plat</th>
    <th class="time">Sch</th>
    <th class="time">Exp</th>
    <th class="time">Sch</th>
    <th class="time">Exp</th>
  </tr>
  <tr>
    <th class="other" colspan="4" />
    <th class="timepair" colspan="2">Arrival</th>
    <th class="timepair" colspan="2">Departure</th>
  </tr>
  {#each services as service}
    {#await generateServiceData(service)}
      <tr><td colspan="8">Loading Service Data...</td></tr>
    {:then serviceData}
      <tr
        class="dataRow"
        on:click={(event) => detail(event, service.rid, service.uid, service.trainid)}
        on:keypress={(event) => detail(event, service.rid, service.uid, service.trainid)}
      >
        <td class="id">{service.trainid}</td>
        <td class="from {serviceData.isNonPublic && 'nonPass'} {serviceData.isCancelled && 'cancTxt'}">{serviceData.from}</td>
        <td class="to {serviceData.isNonPublic && 'nonPass'} {serviceData.isCancelled && 'cancTxt'}">{serviceData.to}</td>
        <td class="plat {serviceData.isNonPublic && 'nonPass'} {serviceData.isCancelled && 'cancTxt'} {serviceData.platformHidden && 'nonPass'}"
          >{serviceData.platform.number || '-'}</td
        >
        <td class="time schTime {serviceData.isNonPublic && 'nonPass'} {serviceData.isCancelled && 'cancTxt'}">{serviceData.schArr}</td>
        <td
          class="time {serviceData.isNonPublic && 'nonPass'} {serviceData.isLateArr && 'late'} {serviceData.isArrDelayed && 'late'} {serviceData.isCancelled &&
            'canc'} {serviceData.isEarlyArr && 'early'}">{serviceData.isArrDelayed ? 'LATE' : serviceData.expArr}</td
        >
        <td class="time schTime {serviceData.isNonPublic && 'nonPass'} {serviceData.isCancelled && 'cancTxt'}">{serviceData.schDep}</td>
        <td
          class="time {serviceData.isNonPublic && 'nonPass'} {serviceData.isLateDep && 'late'} {serviceData.isDepDelayed && 'late'}
                 {serviceData.isCancelled && 'canc'} {serviceData.isEarlyDep && 'early'}">{serviceData.isDepDelayed ? 'LATE' : serviceData.expDep}</td
        >
      </tr>
      <tr>
        <td class="tableTxt" colspan="8">
          {service.operator}
          {#if service.isCharter}charter{/if}
          {#if serviceData.length} | {serviceData.length} carriages{/if}
          {#if service.delayReason}
            <br />
            <Reason type={'delay'} code={service.delayReason} />
          {/if}
          {#if service.cancelReason}
            <br />
            <Reason type={'cancel'} code={service.cancelReason} />
          {/if}
        </td>
      </tr>
    {:catch}
      <tr>
        <td colspan="8">Unable to display service</td>
      </tr>
    {/await}
  {/each}
</table>

<style>
  table {
    table-layout: fixed;
    width: 100%;
    max-width: 875px;
    margin: auto;
    padding: 0px;
    color: white;
  }

  th {
    font-size: 12px;
    margin: 0px;
  }

  .dataRow {
    font-family: ubuntu, monospace;
    vertical-align: bottom;
    cursor: pointer;
    font-size: 16px;
  }

  /* Table Columns */
  .id {
    width: 8%;
  }
  .from {
    width: 14%;
  }
  .to {
    width: 14%;
  }
  .plat {
    width: 6%;
  }
  .time {
    width: 9%;
  }

  td.id {
    color: lightblue;
    text-align: left;
    padding-left: 2px;
  }
  td.from,
  td.to {
    color: yellow;
  }

  td.to,
  th.to {
    text-align: right;
  }
  td.from,
  th.from {
    text-align: left;
  }
  td.time {
    font-size: 15px;
    vertical-align: middle;
  }
  .tableTxt {
    text-align: left;
    padding-left: 2px;
    color: var(--second-text-color);
    vertical-align: top;
    font-size: 12px;
  }

  /* Handle small screens */
  .smallScreen {
    display: none;
    margin: 20px;
  }
  @media screen and (max-width: 335px) {
    th {
      font-size: 10px;
    }
    .dataRow {
      font-size: 12px;
    }
    td.time {
      font-size: 12px;
    }
    .tableTxt {
      font-size: 10px;
    }
  }
  @media screen and (max-width: 279px) {
    table {
      display: none;
    }
    .smallScreen {
      display: block;
    }
  }

  /* Handle Large Screens */
  @media screen and (min-width: 375px) {
    .dataRow {
      font-size: 18px;
    }
    td.time {
      font-size: 16px;
    }
  }
  @media screen and (min-width: 450px) {
    .dataRow {
      font-size: 20px;
    }
    td.time {
      font-size: 19px;
    }
    .tableTxt {
      font-size: 14px;
    }
    td.to,
    td.from,
    th.to,
    th.from {
      text-align: center;
    }
  }

  /* Conditional Classes */
  .cancTxt {
    color: grey !important;
    text-decoration: line-through;
    opacity: 0.8;
  }

  .nonPass {
    opacity: 0.6;
  }

  .late {
    animation: pulse-late 1.5s linear infinite;
  }

  .canc {
    animation: pulse-cancel 1.5s linear infinite;
  }

  .early {
    animation: pulse-early 1.5s linear infinite;
  }

  /* Animation Definitions */
  @keyframes pulse-late {
    50% {
      color: var(--main-warning-color);
    }
  }

  @keyframes pulse-cancel {
    50% {
      color: var(--main-alert-color);
    }
  }

  @keyframes pulse-early {
    50% {
      color: rgb(136, 164, 255);
    }
  }

  /* CARRIED OVER FROM OLD COMPONENT:
  
    #timestamp {
    color: var(--second-text-color);
  }

  .transport-mode {
    width: 30px;
    margin: auto;
  }

  .dataTable {
    color: white;
    font-weight: normal;
    width: 100%;
    margin: 0px, 0px;
    padding-left: 8px;
    padding-right: 8px;
  }

  .id {
    width: 12%;
  }

  .from {
    width: 20%;
  }

  .to {
    width: 20%;
  }

  .plat {
    width: 8%;
  }

  .timePair {
    width: 20%;
  }

  .time {
    width: 10%;
  }

  .data {
    font-weight: normal;
  }

  .id-data {
    color: lightgray;
    text-align: left;
  }

  .from-data,
  .to-data {
    color: yellow;
    text-decoration: none;
    text-align: left;
  }

  .text-row {
    margin-top: 0px;
    padding-bottom: 5px;
    width: 100%;
  }

  .text-data {
    text-align: left;
    color: cyan;
    font-size: smaller;
  }

  .can-dat {
    color: grey;
    text-decoration: line-through;
  }

  .hidden {
    opacity: 0.5;
  }

  .ecs {
    opacity: 0.75;
  }

  .can-time {
    animation: pulse-cancel 1.5s linear infinite;
  }

  .early {
    animation: pulse-early 1.5s linear infinite;
  }

  .late {
    animation: pulse-late 1.5s linear infinite;
  }

  */
</style>
