import isEmpty from 'lodash/isEmpty';
import React, { useContext, useEffect, useMemo, useState } from 'react';
import { RouteComponentProps } from 'react-router-dom';
import { AppMetadataDispatchContext, AppMetadataStateContext } from '../../context/AppMetadataContext';
import { CreateCaseDispatchContext, CreateCaseStateContext } from '../../context/CreateCaseContext';
import { RouteContext, RouteDispatchContext } from '../../context/RouteContext';
import { fetchCaseEntitlements, fetchCaseGroupsForSSO, fetchCaseSeverities, fetchCaseTypes, fetchLanguageMetadata } from '../../reducers/AppMetadataReducer';
import { getUpdatedDescription } from '../../reducers/CreateCaseHelpers';
import { ICreateCaseState, setCaseCreationDetails } from '../../reducers/CreateCaseReducer';
import { AppRouteSections, IRouteUrlParams, RouteReducerConstants } from '../../reducers/RouteReducer';
import RouteUtils from '../../utils/routeUtils';

interface IProps {
  routeProps: RouteComponentProps<IRouteUrlParams>;
}

export default function Issue(props: IProps) {
  const [isIssueSummaryInValid, setIsIssueSummaryInValid] = useState(false);
  const { routeState: { activeSection, isSectionValid, appRouteSectionsSequence } } = useContext(RouteContext);
  const { createCaseState: { summary, issue, environment, periodicityOfIssue, timeFramesAndUrgency } } = useContext(CreateCaseStateContext);
  // getting AppMetaDataState
  const { appMetadataState: {
    nextButtonRef,
    allCaseTypes,
    allCaseSeverities,
    allCaseEntitlements,
    caseLanguages,
    caseGroups,
    loggedInUsersAccount,
    loggedInUserJwtToken
  } } = useContext(AppMetadataStateContext);
  const createCaseDispatch = useContext(CreateCaseDispatchContext);
  const dispatchToRouteReducer = useContext(RouteDispatchContext);
  const dispatchToAppMetadataReducer = useContext(AppMetadataDispatchContext);

  const onCaseDetailsChange = (caseDetails: Partial<ICreateCaseState>) => {
    setCaseCreationDetails(createCaseDispatch, caseDetails);
  };

  // Loading metadata (if needed) on component mount after fetching account info
  useEffect(() => {
      if (isEmpty(loggedInUsersAccount.data)) { return; }
      const allPromisses = [];
      if (isEmpty(allCaseTypes.data)) { allPromisses.push(fetchCaseTypes(dispatchToAppMetadataReducer)); }
      if (isEmpty(allCaseSeverities.data)) { allPromisses.push(fetchCaseSeverities(dispatchToAppMetadataReducer)); }
      if (isEmpty(allCaseEntitlements.data)) { allPromisses.push(fetchCaseEntitlements(dispatchToAppMetadataReducer, loggedInUserJwtToken)); }
      if (isEmpty(caseGroups.data)) { allPromisses.push(fetchCaseGroupsForSSO(dispatchToAppMetadataReducer, loggedInUserJwtToken)); }
      if (isEmpty(caseLanguages.data)) { allPromisses.push(fetchLanguageMetadata(dispatchToAppMetadataReducer)); }
      Promise.all(allPromisses);
  }, [loggedInUsersAccount]);

  const onActivatingIssueSection = (e) => {
    if (activeSection === AppRouteSections.ISSUE) { return; }
    RouteUtils.navigateToSection(props.routeProps, AppRouteSections.ISSUE, appRouteSectionsSequence);
  };
  const onSummaryChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    onCaseDetailsChange({ summary: e.target.value });
    setIsIssueSummaryInValid(isEmpty(e.target.value));
  };
  const onKTQ1IssueChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
    onCaseDetailsChange({ issue: e.target.value });
    const description = getUpdatedDescription(e.target.value, environment, periodicityOfIssue, timeFramesAndUrgency);
    onCaseDetailsChange({ description });
  };
  // Validations effect
  useEffect(() => {
    if (activeSection !== AppRouteSections.ISSUE) { return; }
    const isSectionValidLocal = !isEmpty(summary);
    if (isSectionValid === isSectionValidLocal) { return; }
    dispatchToRouteReducer({ type: RouteReducerConstants.setIsSectionValid, payload: { isSectionValid: isSectionValidLocal } });
  }, [summary, activeSection]);

  const onIssueSummaryBlur = (e: React.FocusEvent<HTMLInputElement>) => {
    setIsIssueSummaryInValid(isEmpty(e.target.value));
  };

  const handleFormSubmit = (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    // simulating click
    nextButtonRef.current.click();
  };

  return useMemo(() => {
    return (<>
      <form onSubmit={handleFormSubmit}>
        <div className="form-group">
          <label htmlFor="issue-summary">Summarize the issue in a few words <span className="form-required">&#42;</span></label>
          <input
            required={true}
            type="text"
            id="issue-summary"
            className={`form-control${isIssueSummaryInValid ? ' form-invalid' : ''}`}
            aria-invalid={isIssueSummaryInValid}
            aria-required={true}
            aria-describedby="issueSummaryDesc"
            name="issue-summary"
            value={summary}
            onClick={onActivatingIssueSection}
            onChange={onSummaryChange}
            onBlur={onIssueSummaryBlur}
          />
          <p className="form-instructions" id="issueSummaryDesc">1-2 sentences</p>
        </div>
        <div className="form-group">
          <label htmlFor="issue-section-ktQ1-issue">If you can, describe the issue in more detail to help improve results</label>
          <textarea
            id="issue-section-ktQ1-issue"
            name="issue-section-ktQ1-issue"
            aria-describedby="describeIssueDesc"
            className="form-control"
            value={issue}
            onClick={onActivatingIssueSection}
            onChange={onKTQ1IssueChange} />
          <p className="form-instructions" id="describeIssueDesc">e.g. What should be happening? What is happening instead?</p>
        </div>
      </form>
    </>);
  }, [props, summary, issue, isIssueSummaryInValid]);
}
