import pick from "lodash/pick";
import { createAsyncAction, errorResult, successResult } from "pullstate";

import { fetch } from "api";
import { ProgramStore } from "stores";

export const loadProgram = createAsyncAction(
  async () => {
    try {
      const resp = await fetch("/program");
      const mappings = await resp.json();
      return successResult(mappings);
    } catch (err) {
      return errorResult([], err.toString());
    }
  },
  {
    postActionHook: ({ result }) => {
      if (!result.error) {
        const entries = result.payload
          .map(
            /**
             *
             * @param {any} entry
             * @returns {CF2021.ProgramScheduleEntry}
             */
            (entry) => {
              return {
                ...pick(entry, [
                  "id",
                  "number",
                  "title",
                  "description",
                  "proposer",
                ]),
                expectedStartAt: new Date(entry.expected_start_at),
                expectedFinishAt: entry.expected_finish_at
                  ? new Date(entry.expected_finish_at)
                  : undefined,
              };
            }
          )
          .sort((a, b) => a.expectedStartAt - b.expectedStartAt);

        const currentEntry = result.payload.find((entry) => entry.is_live);

        ProgramStore.update((state) => {
          state.schedule = entries;

          if (currentEntry) {
            state.current = state.schedule.find(
              (scheduleEntry) => scheduleEntry.id === currentEntry.id
            );
          } else {
            // TODO: for testing only
            state.current = state.schedule[1];
          }
        });
      }
    },
  }
);

/**
 * Open discussion.
 */
export const endProgramPoint = createAsyncAction(
  async () => {
    return successResult();
  },
  {
    postActionHook: ({ result }) => {
      if (!result.error) {
        ProgramStore.update((state) => {
          state.current = null;
        });
      }
    },
  }
);

/**
 * Open discussion.
 */
export const openDiscussion = createAsyncAction(
  async () => {
    return successResult();
  },
  {
    postActionHook: ({ result }) => {
      if (!result.error) {
        ProgramStore.update((state) => {
          state.current.discussionOpened = true;
        });
      }
    },
  }
);

/**
 * Close discussion.
 */
export const closeDiscussion = createAsyncAction(
  async () => {
    return successResult();
  },
  {
    postActionHook: ({ result }) => {
      if (!result.error) {
        ProgramStore.update((state) => {
          state.current.discussionOpened = false;
        });
      }
    },
  }
);