import "core-js/modules/es.array.iterator";
import "core-js/modules/web.dom-collections.iterator";
import _extends from "@babel/runtime-corejs3/helpers/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime-corejs3/helpers/objectWithoutPropertiesLoose";
import _Array$isArray from "@babel/runtime-corejs3/core-js-stable/array/is-array";
import _mapInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/map";
import _reduceInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/reduce";
// @flow
import React, { useState } from 'react';
import { makeStyles, withStyles } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
import Dialog from '@material-ui/core/Dialog';
import TextField from './TextField';
import IconButton from '@material-ui/core/IconButton';
import CloseIcon from '@material-ui/icons/Close';
import Collapse from '@material-ui/core/Collapse';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import Fade from '@material-ui/core/Fade';
import DateFnsUtils from '@date-io/date-fns';
import enLocale from 'date-fns/locale/en-US';
import frLocale from 'date-fns/locale/fr';
import ptLocale from 'date-fns/locale/pt-BR';
import esLocale from 'date-fns/locale/es';
import { MuiPickersUtilsProvider } from '@material-ui/pickers';
import MuiAccordion from '@material-ui/core/Accordion';
import MuiAccordionSummary from '@material-ui/core/AccordionSummary';
import MuiAccordionDetails from '@material-ui/core/AccordionDetails';
import DialogActions from '@material-ui/core/DialogActions';
import MuiDialogContent from '@material-ui/core/DialogContent';
import DialogContentText from '@material-ui/core/DialogContentText';
import DialogTitle from '@material-ui/core/DialogTitle';
import MenuIcon from '@material-ui/icons/MoreVert';
import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';
import { Typography } from '@material-ui/core';
import { useIntl, FormattedMessage, defineMessages } from 'react-intl';
import clone from 'clone-deep';
import FeatureHeader from '../internal/FeatureHeader';
import MediaCarousel from './MediaCarousel';
import { defaultGetPreset } from '../utils/helpers';
import { get, set } from '../utils/get_set';
import Field from './Field';
/*:: import type { Observation } from 'mapeo-schema'*/

/*:: import type {
  PresetWithAdditionalFields,
  GetMedia,
  Attachment,
  Key
} from '../types'*/

const m = defineMessages({
  confirmCloseTitle: {
    "id": "I3F5WA==",
    "defaultMessage": 'Close without saving changes?'
  },
  confirmCloseDescription: {
    "id": "qMB8GQ==",
    "defaultMessage": 'You have made some changes, closing without saving will loose the changes you make'
  },
  confirmCloseButtonConfirm: {
    "id": "yIQFKA==",
    "defaultMessage": 'Discard changes'
  },
  confirmCloseButtonCancel: {
    "id": "FF0Vyg==",
    "defaultMessage": 'Cancel'
  },
  confirmDeleteTitle: {
    "id": "ZjTMNg==",
    "defaultMessage": 'Delete observation?'
  },
  confirmDeleteButtonConfirm: {
    "id": "xxS3fw==",
    "defaultMessage": 'Yes, delete'
  },
  confirmDeleteButtonCancel: {
    "id": "qdS9PA==",
    "defaultMessage": 'Cancel'
  },
  // Header for section that includes the additional details for an observation
  detailsHeader: {
    "id": "uHtAUQ==",
    "defaultMessage": 'Details'
  },
  // Header for section with additional fields that are not defined in the preset
  additionalHeader: {
    "id": "7EPUxA==",
    "defaultMessage": 'Additional data'
  },
  // Cancel button once observation has been edited
  cancelEditButton: {
    "id": "bjpM6A==",
    "defaultMessage": 'Cancel'
  },
  // Save edit button
  saveEditButton: {
    "id": "3StVcg==",
    "defaultMessage": 'Save'
  },
  // Menu item to delete an observation
  deleteObservationMenuItem: {
    "id": "o+27Wg==",
    "defaultMessage": 'Delete observation'
  }
});
/*:: type ImageMediaItem = {
  src: string,
  type: 'image'
}*/

/*:: type Props = {
  open?: boolean,
  onRequestClose: () => void,
  onDelete: (id: string) => void,
  observation: Observation,
  // The initial image to show in the media carousel
  initialImageIndex?: number,
  onSave: (observation: Observation) => void,
  getPreset?: Observation => PresetWithAdditionalFields | void,
  /**
   * For a given attachment, return `src` and `type`
   *-/
  getMedia: GetMedia
}*/

const localeMap = {
  en: enLocale,
  fr: frLocale,
  pt: ptLocale,
  es: esLocale
};

function getLocaleData(locale) {
  if (!locale) return localeMap.en;
  return localeMap[locale] || localeMap[locale.split('-')[0]] || localeMap.en;
}

function defaultGetMedia({
  type,
  id
}
/*: Attachment*/
) {
  if (type && type.split('/')[0] !== 'image') return;
  return {
    type: 'image',
    src: id
  };
}

const ConfirmCloseDialog = ({
  open,
  onCancel,
  onConfirm
}) => /*#__PURE__*/React.createElement(Dialog, {
  disableBackdropClick: true,
  open: open,
  onClose: onCancel,
  "aria-labelledby": "close-dialog-title",
  "aria-describedby": "close-dialog-description"
}, /*#__PURE__*/React.createElement(DialogTitle, {
  id: "close-dialog-title"
}, /*#__PURE__*/React.createElement(FormattedMessage, m.confirmCloseTitle)), /*#__PURE__*/React.createElement(MuiDialogContent, null, /*#__PURE__*/React.createElement(DialogContentText, {
  id: "close-dialog-description"
}, /*#__PURE__*/React.createElement(FormattedMessage, m.confirmCloseDescription))), /*#__PURE__*/React.createElement(DialogActions, null, /*#__PURE__*/React.createElement(Button, {
  onClick: onCancel,
  color: "primary"
}, /*#__PURE__*/React.createElement(FormattedMessage, m.confirmCloseButtonCancel)), /*#__PURE__*/React.createElement(Button, {
  onClick: onConfirm,
  color: "primary",
  autoFocus: true
}, /*#__PURE__*/React.createElement(FormattedMessage, m.confirmCloseButtonConfirm))));

const ConfirmDeleteDialog = ({
  open,
  onCancel,
  onConfirm
}) => /*#__PURE__*/React.createElement(Dialog, {
  disableBackdropClick: true,
  open: open,
  onClose: onCancel,
  "aria-labelledby": "delete-dialog-title"
}, /*#__PURE__*/React.createElement(DialogTitle, {
  id: "delete-dialog-title"
}, /*#__PURE__*/React.createElement(FormattedMessage, m.confirmDeleteTitle)), /*#__PURE__*/React.createElement(DialogActions, null, /*#__PURE__*/React.createElement(Button, {
  onClick: onCancel,
  color: "primary"
}, /*#__PURE__*/React.createElement(FormattedMessage, m.confirmDeleteButtonCancel)), /*#__PURE__*/React.createElement(Button, {
  onClick: onConfirm,
  color: "primary",
  autoFocus: true
}, /*#__PURE__*/React.createElement(FormattedMessage, m.confirmDeleteButtonConfirm))));

const Accordion = withStyles({
  root: {
    border: '1px solid rgba(0, 0, 0, .125)',
    boxShadow: 'none',
    '&:before': {
      display: 'none'
    },
    '&$expanded': {
      margin: 'auto'
    }
  },
  expanded: {}
})(MuiAccordion);
const AccordionSummary = withStyles({
  root: {
    '&$expanded': {
      minHeight: 48
    }
  },
  content: {
    '&$expanded': {
      margin: '12px 0'
    }
  },
  expanded: {}
})(MuiAccordionSummary);
const AccordionDetails = withStyles({
  root: {
    display: 'flex',
    flexDirection: 'column',
    flexWrap: 'wrap',
    padding: '0 21px 10px 21px',
    '& > div:first-child': {
      marginTop: 10
    }
  }
})(MuiAccordionDetails);

const ObservationActions = ({
  onDeleteClick
}) => {
  const [anchorEl, setAnchorEl] = React.useState(null);
  const [confirm, setConfirm] = useState(null);

  const handleOpenClick = event => {
    setAnchorEl(event.currentTarget);
  };

  const handleClose = () => {
    setAnchorEl(null);
  };

  const createHandleItemClick = (action
  /*: () => any*/
  = () => {}) => () => {
    // Can't setState to a function
    setConfirm(state => didConfirm => {
      setConfirm(null);
      if (didConfirm) action();
      handleClose();
    });
  };

  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(IconButton, {
    "aria-controls": "simple-menu",
    "aria-haspopup": "true",
    onClick: handleOpenClick
  }, /*#__PURE__*/React.createElement(MenuIcon, null)), /*#__PURE__*/React.createElement(Menu, {
    id: "simple-menu",
    anchorEl: anchorEl,
    keepMounted: true,
    open: Boolean(anchorEl),
    onClose: handleClose
  }, /*#__PURE__*/React.createElement(MenuItem, {
    onClick: createHandleItemClick(onDeleteClick)
  }, /*#__PURE__*/React.createElement(FormattedMessage, m.deleteObservationMenuItem))), /*#__PURE__*/React.createElement(ConfirmDeleteDialog, {
    open: !!confirm,
    onConfirm: () => confirm && confirm(true),
    onCancel: () => confirm && confirm(false)
  }));
};

const DialogContent = ({
  open = false,
  onRequestClose,
  onSave,
  onDelete,
  observation,
  initialImageIndex,
  getPreset = defaultGetPreset,
  getMedia = defaultGetMedia
}
/*: {
  ...$Exact<Props>,
  onRequestClose: (shouldConfirm: boolean) => void
}*/
) => {
  var _context, _context2, _context3;

  const cx = useStyles();
  const [values, setValues] = useState(observation.tags ? clone(observation.tags) : {});
  const [dirty, setDirty] = useState(false);
  const {
    locale
  } = useIntl();

  const handleSave = () => {
    onSave(set(observation, 'tags', values));
    onRequestClose(false);
  };

  const handleRequestClose = () => {
    // Ask for confirmation if form is dirty
    onRequestClose(dirty);
  };

  const handleDeleteClick = () => {
    onRequestClose(false);
    onDelete(observation.id);
  };

  const handleChange = (key
  /*: Key*/
  , newValue
  /*: any*/
  ) => {
    setDirty(true);
    setValues(set(values, key, newValue));
  };

  const preset = getPreset(observation) || {};
  const coords = observation.lat != null && observation.lon != null ? {
    latitude: observation.lat,
    longitude: observation.lon
  } : undefined;
  const descriptionKey = values.note ? 'note' : 'notes';

  const mediaItems
  /*: ImageMediaItem[]*/
  = _reduceInstanceProperty(_context = observation.attachments || []).call(_context, (acc, cur) => {
    const item = getMedia(cur, {
      width: 800,
      height: 600
    }); // $FlowFixMe - need to fix type refinement here

    if (item && item.type === 'image') acc.push(item);
    return acc;
  }, []);

  return /*#__PURE__*/React.createElement(MuiPickersUtilsProvider, {
    utils: DateFnsUtils,
    locale: getLocaleData(locale)
  }, /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(IconButton, {
    className: cx.closeButton,
    color: "inherit",
    onClick: handleRequestClose,
    "aria-label": "Close"
  }, /*#__PURE__*/React.createElement(CloseIcon, null)), mediaItems.length > 0 && /*#__PURE__*/React.createElement("div", {
    className: cx.mediaWrapper
  }, /*#__PURE__*/React.createElement(MediaCarousel, {
    items: mediaItems,
    initialIndex: initialImageIndex,
    className: cx.media
  })), /*#__PURE__*/React.createElement(FeatureHeader, {
    icon: preset.icon,
    name: preset.name,
    coords: coords,
    createdAt: new Date(observation.created_at),
    action: /*#__PURE__*/React.createElement(ObservationActions, {
      onDeleteClick: handleDeleteClick
    })
  }), /*#__PURE__*/React.createElement(TextField, {
    value: values[descriptionKey],
    onChange: newValue => handleChange(descriptionKey, newValue),
    multiline: true,
    margin: "dense",
    label: "Description",
    className: cx.descriptionField
  }), preset.fields.length > 0 && /*#__PURE__*/React.createElement(Accordion, {
    TransitionProps: {
      unmountOnExit: true
    }
  }, /*#__PURE__*/React.createElement(AccordionSummary, {
    expandIcon: /*#__PURE__*/React.createElement(ExpandMoreIcon, null),
    "aria-controls": "panel1a-content",
    id: "panel1a-header"
  }, /*#__PURE__*/React.createElement(Typography, {
    component: "h2",
    className: cx.sectionHeading
  }, /*#__PURE__*/React.createElement(FormattedMessage, m.detailsHeader))), /*#__PURE__*/React.createElement(AccordionDetails, null, _mapInstanceProperty(_context2 = preset.fields).call(_context2, field => /*#__PURE__*/React.createElement(Field, {
    key: field.id,
    field: field,
    value: get(values, field.key),
    onChange: handleChange
  })))), _Array$isArray(preset.additionalFields) && preset.additionalFields.length > 0 && /*#__PURE__*/React.createElement(Accordion, null, /*#__PURE__*/React.createElement(AccordionSummary, {
    expandIcon: /*#__PURE__*/React.createElement(ExpandMoreIcon, null),
    "aria-controls": "panel1a-content",
    id: "panel1a-header"
  }, /*#__PURE__*/React.createElement(Typography, {
    component: "h2",
    className: cx.sectionHeading
  }, /*#__PURE__*/React.createElement(FormattedMessage, m.additionalHeader))), /*#__PURE__*/React.createElement(AccordionDetails, null, _mapInstanceProperty(_context3 = preset.additionalFields).call(_context3, field => /*#__PURE__*/React.createElement(Field, {
    key: field.id,
    field: field,
    value: get(values, field.key),
    onChange: handleChange
  })))), /*#__PURE__*/React.createElement(Fade, {
    in: dirty
  }, /*#__PURE__*/React.createElement(Collapse, {
    in: dirty,
    className: cx.actions
  }, /*#__PURE__*/React.createElement(Button, {
    color: "default",
    variant: "contained",
    className: cx.button,
    onClick: handleRequestClose
  }, /*#__PURE__*/React.createElement(FormattedMessage, m.cancelEditButton)), /*#__PURE__*/React.createElement(Button, {
    color: "primary",
    variant: "contained",
    className: cx.button,
    onClick: handleSave
  }, /*#__PURE__*/React.createElement(FormattedMessage, m.saveEditButton))))));
};

const ObservationDialog = (_ref) => {
  let {
    open,
    onRequestClose
  }
  /*: Props*/
  = _ref,
      otherProps = _objectWithoutPropertiesLoose(_ref, ["open", "onRequestClose"]);

  const [confirm, setConfirm] = useState(null);

  const handleRequestClose = shouldConfirm => {
    if (!shouldConfirm) {
      setConfirm(null);
      onRequestClose();
      return;
    }

    setConfirm(state => didConfirm => {
      setConfirm(null);
      if (didConfirm) onRequestClose();
    });
  };

  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Dialog, {
    disableBackdropClick: true,
    open: open,
    onClose: handleRequestClose,
    scroll: "body",
    fullWidth: true,
    maxWidth: "sm"
  }, open && /*#__PURE__*/React.createElement(DialogContent, _extends({}, otherProps, {
    onRequestClose: handleRequestClose
  }))), /*#__PURE__*/React.createElement(ConfirmCloseDialog, {
    open: !!confirm,
    onConfirm: () => confirm && confirm(true),
    onCancel: () => confirm && confirm(false)
  }));
};

export default ObservationDialog;
const useStyles = makeStyles(theme => ({
  closeButton: {
    position: 'absolute',
    zIndex: 999,
    left: 0,
    top: 0,
    color: 'white',
    backgroundColor: 'rgba(0,0,0,0.4)',
    borderRadius: '0 0 4px 0',
    '&:hover': {
      backgroundColor: 'rgba(0,0,0,0.5)'
    }
  },
  descriptionField: {
    boxSizing: 'border-box',
    margin: '0 10px 13.5px 10px',
    width: 'calc(100% - 20px)',
    '& .MuiInputBase-inputMultiline': theme.typography.body1,
    '& .MuiInputLabel-root': {
      opacity: 0,
      transition: 'opacity 200ms cubic-bezier(0.0, 0, 0.2, 1)'
    },
    '&:hover .MuiInputLabel-root, & .MuiInputLabel-root.Mui-focused': {
      opacity: 1
    },
    '& .MuiOutlinedInput-notchedOutline': {
      borderColor: 'rgba(0,0,0,0)'
    }
  },
  sectionHeading: {
    fontWeight: 500
  },
  mediaWrapper: {
    width: '100%',
    paddingTop: '75%',
    position: 'relative',
    height: 0
  },
  media: {
    position: 'absolute',
    top: 0,
    left: 0,
    width: '100%',
    height: '100%'
  },
  details: {
    flexDirection: 'column',
    flex: 1,
    minWidth: 320,
    flexBasis: '33%',
    backgroundColor: 'white',
    overflowY: 'scroll'
  },
  actions: {
    margin: '0 10px',
    textAlign: 'right'
  },
  button: {
    marginLeft: theme.spacing(1),
    marginTop: 14,
    marginBottom: 14
  }
}));
//# sourceMappingURL=ObservationDialog.js.map