import { get } from 'lodash';
import moment from 'moment';

import EDGE_EVENT from '../constant/relationship/edge-event.constant';
import RELATIONSHIP_LABEL from '../constant/relationship/label.constant';
import RelationshipHelper from './relationship.helper';

const {
  EDGE_TYPE: { EVENT },
  NODE: { BUA, GROUP, LAB_HAZARD, ROOM },
} = RELATIONSHIP_LABEL;

export function hasCertifiedOrAcknowledged(events = []) {
  return events.some((e) => [EDGE_EVENT.ACKNOWLEDGED, EDGE_EVENT.CERTIFIED].includes(e));
}

const hasAssessmentCompleted = (assessment, type) => {
  switch (type) {
    case LAB_HAZARD:
      return Boolean(assessment.expirationDate);
    case BUA:
      return !['AMEND', 'AMENDMENT_DRAFT', 'DRAFT', 'RENEWAL_DRAFT'].includes(assessment.status);
    default:
      break;
  }
  return false;
};

export function didUserComplete(assessment, userId, isAdmin) {
  const {
    relationships = [],
    status,
    template: { assessmentTypeConfig = {} },
  } = assessment || {};

  if (isAdmin) {
    return hasAssessmentCompleted(assessment, assessmentTypeConfig.type);
  }

  const events = relationships
    .filter((relationship) => relationship.node.id === userId && relationship.edge.type === EVENT)
    .map((l) => l.edge.label);
  if (assessmentTypeConfig.type === BUA) {
    return (
      !['AMEND', 'AMENDMENT_DRAFT', 'DRAFT', 'RENEWAL_DRAFT'].includes(status) && !hasCertifiedOrAcknowledged(events)
    );
  }
  return hasCertifiedOrAcknowledged(events);
}

export function hasOutcomes(assessment) {
  const report = assessment.report.outcomes || assessment.report.summary;
  return Object.values(report).some((value) => value.length);
}

export function hasSomeResponse(assessment) {
  const { responses } = assessment;
  return responses && Object.keys(responses).length;
}

export function isSectionComplete(assessment, section) {
  const { responses } = assessment;

  if (section.questions.every((question) => !question.required)) {
    return true;
  }

  // TODO: check nested questions
  return (
    responses &&
    responses[section.key] &&
    section.questions.every((question) => {
      const questionResponses = responses[section.key][question.key];
      if (Array.isArray(questionResponses)) {
        return questionResponses.length > 0;
      }
      return questionResponses || !question.required;
    })
  );
}

export function filterIncompleteSections(template, assessment) {
  return template.questions.filter((section) => !isSectionComplete(assessment, section));
}

export function getEventDate(assessment, eventType) {
  const events = assessment.relationships.filter(
    (r) => get(r, 'edge.type') === EVENT && get(r, 'edge.label') === eventType,
  );
  const lastEventDate = events.length && new Date(Math.max(...events.map((e) => new Date(e.edge.startDate))));
  return lastEventDate ? moment(lastEventDate) : '';
}

export function isAssessmentFormComplete(assessment) {
  const { relationships, template } = assessment;
  const incompleteSections = filterIncompleteSections(template, assessment);
  if (template.parentType === GROUP) {
    const hasLocations = RelationshipHelper.hasAnyOfTypes(relationships, [ROOM]);
    return hasLocations && !incompleteSections.length;
  }
  return !incompleteSections.length;
}

export default {
  didUserComplete,
  filterIncompleteSections,
  getEventDate,
  hasCertifiedOrAcknowledged,
  hasOutcomes,
  hasSomeResponse,
  isAssessmentFormComplete,
  isSectionComplete,
};
