// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import {ReactElement} from 'react';
import * as React from 'react'
import ReactDOM from 'react-dom';
import styles from './IssueWizard.css';
import LandingStep from './issue-wizard/LandingStep.tsx';
import DetailsStep from './issue-wizard/DetailsStep.tsx'
import {IssueWizardPersona} from './issue-wizard/IssueWizardTypes.tsx';
import CustomQuestionsStep from './issue-wizard/CustomQuestionsStep.tsx';
import {getOs, getChromeVersion, buildIssueDescription} from './issue-wizard/IssueWizardUtils.tsx'
import Header from './issue-wizard/Header.tsx'

import {GetQuestionsByCategory, buildIssueLabels, getCompValByCategory, getLabelsByCategory} from './issue-wizard/IssueWizardUtils.tsx';
import {ISSUE_WIZARD_QUESTIONS, ISSUE_REPRODUCE_PLACEHOLDER, OS_CHANNEL_LIST} from './issue-wizard/IssueWizardConfig.ts';
import {prpcClient} from 'prpc-client-instance.js';
import {expandDescriptions} from './issue-wizard/IssueWizardDescriptionsUtils.tsx';
import SubmitSuccessStep from './issue-wizard/SubmitSuccessStep.tsx';
import {IssueWizardFeedback} from './issue-wizard/IssueWizardFeedback.tsx';

/**
 * Base component for the issue filing wizard, wrapper for other components.
 * @return Issue wizard JSX.
 */
 type Props = {
  loginUrl: string,
  userDisplayName: string,
}
export function IssueWizard(props: Props): ReactElement {
  const {loginUrl, userDisplayName} = props;
  React.useEffect(() => {
    if(!userDisplayName) {
      window.location.href = loginUrl;
    }
  },[loginUrl, userDisplayName]);

  const [userPersona, setUserPersona] = React.useState(IssueWizardPersona.EndUser);
  const [activeStep, setActiveStep] = React.useState(0);
  const [category, setCategory] = React.useState('');
  const [newIssueID, setnewIssueID] = React.useState('');
  const [isRegression, setIsRegression] = React.useState(false);
  const [textValues, setTextValues] = React.useState(
    {
      oneLineSummary: '',
      stepsToReproduce: ISSUE_REPRODUCE_PLACEHOLDER,
      describeProblem: '',
      chromeVersion: getChromeVersion(),
      osName: getOs(),
      channel: OS_CHANNEL_LIST[0].name,
    });
  const [enableFeedback, setEnableFeedback] = React.useState(false);
  const questionByCategory = GetQuestionsByCategory(ISSUE_WIZARD_QUESTIONS);

  const moveStep = (step: number) => {
    window.scrollTo(0, 0);
    setActiveStep(step);
  }

  const reset = () => {
    setTextValues({
      oneLineSummary: '',
      stepsToReproduce: ISSUE_REPRODUCE_PLACEHOLDER,
      describeProblem: '',
      chromeVersion: getChromeVersion(),
      osName: getOs(),
      channel: OS_CHANNEL_LIST[0].name,
    });
    setIsRegression(false);
  }

  const updateCategory = (category: string) => {
    setCategory(category);
    reset();
  }

  let page;
  if (activeStep === 0) {
    page = <LandingStep
        userPersona={userPersona}
        setUserPersona={setUserPersona}
        category={category}
        setCategory={updateCategory}
        setActiveStep={moveStep}
        />;
      } else if (activeStep === 1) {
        page = <DetailsStep
          textValues={textValues}
          setTextValues={setTextValues}
          category={category}
          setActiveStep={moveStep}
          setIsRegression={setIsRegression}
    />;
   } else if (activeStep === 2) {
    const compValByCategory = getCompValByCategory(ISSUE_WIZARD_QUESTIONS);
    const labelsByCategory = getLabelsByCategory(ISSUE_WIZARD_QUESTIONS);

    const onSubmitIssue = (comments: string, customQuestionsAnswers: Array<string>, attachments: Array<any>,onSuccess: Function, onFailure: Function) => {
      const summary = textValues.oneLineSummary;
      const component =  compValByCategory.get(category);
      const description = buildIssueDescription(
        textValues.stepsToReproduce,
        textValues.describeProblem,
        comments, textValues.osName,
        textValues.chromeVersion,
        textValues.channel);
      const labels = buildIssueLabels(category, textValues.osName, textValues.chromeVersion, labelsByCategory.get(category));

      const {expandDescription, expandLabels, compVal} =
        expandDescriptions(category, customQuestionsAnswers, isRegression, description, labels, component);

      const componentsArray = [];
      if (compVal.length > 0) {
        componentsArray.push({
          component: 'projects/chromium/componentDefs/' + compVal
        })
      }

      const response = prpcClient.call('monorail.v3.Issues', 'MakeIssue', {
        parent: 'projects/chromium',
        issue: {
          summary,
          status: {
            status: 'Untriaged',
          },
          components: componentsArray,
          labels: expandLabels,
        },
        description: expandDescription,
        uploads: attachments,
        });
        response.then(onSuccess, onFailure);
    }
    page =
      <CustomQuestionsStep
        setActiveStep={moveStep}
        questions={questionByCategory.get(category)}
        onSubmit={onSubmitIssue}
        setnewIssueID={setnewIssueID}
      />;
  } else if (activeStep === 3) {
    page = <SubmitSuccessStep issueID={newIssueID}/>;
  }

  return (
    <>
      <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Poppins"></link>
      <div className={styles.container}>
        <Header />
        {page}
        <div className={styles.feedback} onClick={()=>{setEnableFeedback(true);}}>Report a problem with this wizard</div>
      </div>
      <IssueWizardFeedback enable={enableFeedback} setEnable={setEnableFeedback}/>
    </>
  );
}

/**
 * Renders the issue filing wizard page.
 * @param mount HTMLElement that the React component should be added to.
 * @param loginUrl redirect to login page
 * @param userDisplayName login user
 */
export function renderWizard(mount: HTMLElement, loginUrl: string, userDisplayName: string): void {
  ReactDOM.render(<IssueWizard loginUrl={loginUrl} userDisplayName={userDisplayName}/>, mount);
}
