// @flow

import {
  type ClientReportCreationRequest,
  type ReportCreationResponse,
  type ClearDeliveredReportsPayload,
  queuedClientReportCreationRequestPropType,
} from '../types/report-types';
import type { DispatchActionPromise } from '../utils/action-utils';
import type { AppState } from '../types/redux-types';

import * as React from 'react';
import PropTypes from 'prop-types';

import { connect } from '../utils/redux-utils';
import { sendReportActionTypes, sendReport } from '../actions/report-actions';
import { queuedReports } from '../selectors/socket-selectors';
import { ServerError } from '../utils/errors';

type Props = {|
  canSendReports: boolean,
  // Redux state
  queuedReports: $ReadOnlyArray<ClientReportCreationRequest>,
  // Redux dispatch functions
  dispatchActionPromise: DispatchActionPromise,
  // async functions that hit server APIs
  sendReport: (
    request: ClientReportCreationRequest,
  ) => Promise<ReportCreationResponse>,
|};
class ReportHandler extends React.PureComponent<Props> {
  static propTypes = {
    canSendReports: PropTypes.bool.isRequired,
    queuedReports: PropTypes.arrayOf(queuedClientReportCreationRequestPropType)
      .isRequired,
    dispatchActionPromise: PropTypes.func.isRequired,
    sendReport: PropTypes.func.isRequired,
  };

  componentDidMount() {
    if (this.props.canSendReports) {
      this.sendResponses(this.props.queuedReports);
    }
  }

  componentDidUpdate(prevProps: Props) {
    if (!this.props.canSendReports) {
      return;
    }

    const couldSend = prevProps.canSendReports;
    const curReports = this.props.queuedReports;
    if (!couldSend) {
      this.sendResponses(curReports);
      return;
    }

    const prevReports = prevProps.queuedReports;
    if (curReports !== prevReports) {
      const prevResponses = new Set(prevReports);
      const newResponses = curReports.filter(
        response => !prevResponses.has(response),
      );
      this.sendResponses(newResponses);
    }
  }

  render() {
    return null;
  }

  sendResponses(responses: $ReadOnlyArray<ClientReportCreationRequest>) {
    for (let response of responses) {
      this.props.dispatchActionPromise(
        sendReportActionTypes,
        this.sendResponse(response),
      );
    }
  }

  async sendResponse(report: ClientReportCreationRequest) {
    await this.sendReport(report);
    return ({ reports: [report] }: ClearDeliveredReportsPayload);
  }

  async sendReport(report: ClientReportCreationRequest) {
    try {
      await this.props.sendReport(report);
    } catch (e) {
      if (e instanceof ServerError && e.message === 'ignored_report') {
        // nothing
      } else {
        throw e;
      }
    }
  }
}

export default connect(
  (state: AppState) => ({
    queuedReports: queuedReports(state),
  }),
  { sendReport },
)(ReportHandler);

@@ -52,39 +52,8 @@
 st,%0A
-  type ReportCreationResponse,%0A
   ty
@@ -413,32 +413,33 @@
 ort %7B sendReport
+s
 ActionTypes, sen
@@ -445,16 +445,17 @@
 ndReport
+s
  %7D from 
@@ -549,55 +549,8 @@
 rs';
-%0Aimport %7B ServerError %7D from '../utils/errors';
 %0A%0Aty
@@ -801,16 +801,17 @@
 ndReport
+s
 : (%0A    
@@ -816,15 +816,30 @@
   re
-quest: 
+ports: $ReadOnlyArray%3C
 Clie
@@ -857,24 +857,25 @@
 ationRequest
+%3E
 ,%0A  ) =%3E Pro
@@ -883,30 +883,12 @@
 ise%3C
-ReportCreationResponse
+void
 %3E,%0A%7C
@@ -1184,16 +1184,17 @@
 ndReport
+s
 : PropTy
@@ -1292,28 +1292,34 @@
    this.
-s
+dispatchS
 endRe
-s
 po
-nse
+rt
 s(this.p
@@ -1580,28 +1580,34 @@
    this.
-s
+dispatchS
 endRe
-s
 po
-nse
+rt
 s(curRep
@@ -1887,28 +1887,34 @@
    this.
-s
+dispatchS
 endRe
-s
 po
-nse
+rt
 s(newRes
@@ -1974,30 +1974,34 @@
 %0A%0A  
-s
+dispatchS
 endRe
-s
 po
-nse
+rt
 s(re
-s
 po
-nse
+rt
 s: $
@@ -2054,44 +2054,56 @@
     
-for (let 
+if (
 re
-s
 po
-nse of responses) %7B%0A  
+rts.length === 0) %7B%0A      return;%0A    %7D%0A
     
@@ -2136,18 +2136,16 @@
 romise(%0A
-  
       se
@@ -2152,16 +2152,17 @@
 ndReport
+s
 ActionTy
@@ -2168,26 +2168,24 @@
 ypes,%0A      
-  
 this.sendRes
@@ -2187,41 +2187,31 @@
 ndRe
-s
 po
-nse
+rts
 (re
-s
 po
-nse
+rts
 ),%0A    
-  
 );%0A
-    %7D%0A
   %7D%0A
@@ -2229,23 +2229,38 @@
 ndRe
-s
 po
-nse
+rts
 (report
+s
 : 
+$ReadOnlyArray%3C
 Clie
@@ -2274,32 +2274,33 @@
 tCreationRequest
+%3E
 ) %7B%0A    await th
@@ -2298,24 +2298,30 @@
  await this.
+props.
 sendReport(r
@@ -2314,31 +2314,33 @@
 s.sendReport
+s
 (report
+s
 );%0A    retur
@@ -2355,18 +2355,8 @@
 orts
-: %5Breport%5D
  %7D: 
@@ -2393,279 +2393,8 @@
 %0A  %7D
-%0A%0A  async sendReport(report: ClientReportCreationRequest) %7B%0A    try %7B%0A      await this.props.sendReport(report);%0A    %7D catch (e) %7B%0A      if (e instanceof ServerError && e.message === 'ignored_report') %7B%0A        // nothing%0A      %7D else %7B%0A        throw e;%0A      %7D%0A    %7D%0A  %7D
 %0A%7D%0A%0A
@@ -2504,16 +2504,17 @@
 ndReport
+s
  %7D,%0A)(Re

Use new multi-report creation endpoint in ReportHandler