import { useAgent } from '@aries-framework/react-hooks';
import { ProofRequestType, linkProofWithTemplate, sendProofRequest } from '@hyperledger/aries-bifold-verifier';
import { MetaOverlay } from '@hyperledger/aries-oca';
import { Attribute, Predicate } from '@hyperledger/aries-oca/build/legacy';
import { OverlayType } from '@hyperledger/aries-oca/build/types/TypeEnums';
import React, { useCallback, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { FlatList, StyleSheet, Text, TextInput, View } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import Button, { ButtonType } from '../components/buttons/Button';
import AlertModal from '../components/modals/AlertModal';
import { useConfiguration } from '../contexts/configuration';
import { useStore } from '../contexts/store';
import { useTheme } from '../contexts/theme';
import { useTemplate } from '../hooks/proof-request-templates';
import { Screens } from '../types/navigators';
import { formatIfDate, pTypeToText } from '../utils/helpers';
import { buildFieldsFromAnonCredsProofRequestTemplate } from '../utils/oca';
import { parseSchemaFromId } from '../utils/schema';
import { testIdWithKey } from '../utils/testable';
const AttributeItem = _ref => {
  let {
    item,
    style
  } = _ref;
  const [value, setValue] = useState(item.value);
  useEffect(() => {
    setValue(formatIfDate(item.format, value));
  }, []);
  return /*#__PURE__*/React.createElement(View, {
    style: {
      flexDirection: 'row'
    }
  }, /*#__PURE__*/React.createElement(Text, {
    style: style
  }, item.label || item.name), /*#__PURE__*/React.createElement(Text, {
    style: style
  }, value));
};
const PredicateItem = _ref2 => {
  let {
    item,
    style,
    onChangeValue
  } = _ref2;
  const {
    ColorPallet
  } = useTheme();
  const defaultStyle = StyleSheet.create({
    input: {
      textAlign: 'center',
      borderBottomColor: ColorPallet.grayscale.black,
      borderBottomWidth: 1
    }
  });
  return /*#__PURE__*/React.createElement(View, {
    style: {
      flexDirection: 'row',
      flexWrap: 'wrap'
    }
  }, /*#__PURE__*/React.createElement(Text, {
    style: style
  }, item.label || item.name), /*#__PURE__*/React.createElement(Text, {
    style: style
  }, item.pType), item.parameterizable && /*#__PURE__*/React.createElement(TextInput, {
    keyboardType: "numeric",
    style: [style, defaultStyle.input],
    onChangeText: value => onChangeValue(item.name || '', value)
  }, item.pValue), !item.parameterizable && /*#__PURE__*/React.createElement(Text, {
    style: style
  }, item.pValue));
};
const ProofRequestAttributesCard = _ref3 => {
  let {
    data,
    onChangeValue
  } = _ref3;
  const {
    ListItems,
    ColorPallet
  } = useTheme();
  const {
    t,
    i18n
  } = useTranslation();
  const {
    OCABundleResolver
  } = useConfiguration();
  const style = StyleSheet.create({
    credentialCard: {
      ...ListItems.requestTemplateBackground,
      padding: 16,
      borderRadius: 8,
      borderLeftWidth: 8,
      borderLeftColor: ColorPallet.brand.primary,
      marginBottom: 16
    },
    schemaTitle: {
      ...ListItems.requestTemplateTitle,
      fontWeight: 'bold',
      fontSize: 20,
      paddingVertical: 8
    },
    attributeTitle: {
      ...ListItems.requestTemplateTitle,
      fontWeight: 'bold',
      fontSize: 18,
      marginRight: 8
    },
    attributesList: {
      paddingLeft: 14
    },
    fieldContainer: {
      flexDirection: 'row',
      paddingVertical: 8
    }
  });
  const [meta, setMeta] = useState(undefined);
  const [attributes, setAttributes] = useState(undefined);
  const [attributeTypes, setAttributeTypes] = useState(undefined);
  const [attributeFormats, setAttributeFormats] = useState(undefined);
  useEffect(() => {
    OCABundleResolver.resolve({
      identifiers: {
        schemaId: data.schema
      },
      language: i18n.language
    }).then(bundle => {
      const metaOverlay = (bundle === null || bundle === void 0 ? void 0 : bundle.metaOverlay) || new MetaOverlay({
        capture_base: '',
        type: OverlayType.Meta10,
        name: parseSchemaFromId(data.schema).name,
        description: '',
        language: i18n.language,
        credential_help_text: '',
        credential_support_url: '',
        issuer: '',
        issuer_description: '',
        issuer_url: ''
      });
      setMeta(metaOverlay);
    });
    const attributes = buildFieldsFromAnonCredsProofRequestTemplate(data);
    OCABundleResolver.presentationFields({
      identifiers: {
        schemaId: data.schema
      },
      attributes,
      language: i18n.language
    }).then(fields => {
      setAttributes(fields);
    });
  }, [data.schema]);
  useEffect(() => {
    var _ref4;
    const credDefId = (_ref4 = data.requestedAttributes ?? data.requestedPredicates) === null || _ref4 === void 0 ? void 0 : _ref4.flatMap(reqItem => {
      var _reqItem$restrictions;
      return (_reqItem$restrictions = reqItem.restrictions) === null || _reqItem$restrictions === void 0 ? void 0 : _reqItem$restrictions.map(restrictionItem => restrictionItem.cred_def_id);
    }).find(item => item !== undefined);
    const params = {
      identifiers: {
        credentialDefinitionId: credDefId,
        schemaId: data.schema
      },
      language: i18n.language,
      attributes
    };
    OCABundleResolver.resolveAllBundles(params).then(bundle => {
      var _bundle$bundle, _bundle$bundle2;
      setAttributeTypes(bundle === null || bundle === void 0 ? void 0 : (_bundle$bundle = bundle.bundle) === null || _bundle$bundle === void 0 ? void 0 : _bundle$bundle.captureBase.attributes);
      setAttributeFormats((_bundle$bundle2 = bundle.bundle) === null || _bundle$bundle2 === void 0 ? void 0 : _bundle$bundle2.bundle.attributes.map(attr => {
        return {
          name: attr.name,
          format: attr.format
        };
      }).reduce((prev, curr) => {
        return {
          ...prev,
          [curr.name]: curr.format
        };
      }, {}));
    });
  }, []);
  return /*#__PURE__*/React.createElement(View, {
    style: [style.credentialCard]
  }, /*#__PURE__*/React.createElement(Text, {
    style: style.schemaTitle
  }, meta === null || meta === void 0 ? void 0 : meta.name), /*#__PURE__*/React.createElement(FlatList, {
    style: style.attributesList,
    data: attributes,
    keyExtractor: (record, index) => record.name || index.toString(),
    renderItem: _ref5 => {
      let {
        item
      } = _ref5;
      item.format = attributeFormats === null || attributeFormats === void 0 ? void 0 : attributeFormats[item.name ?? ''];
      let parsedPredicate = undefined;
      if (item instanceof Predicate) {
        parsedPredicate = pTypeToText(item, t, attributeTypes);
        if (!parsedPredicate.parameterizable) {
          parsedPredicate.pValue = formatIfDate(parsedPredicate.format, parsedPredicate.pValue);
        }
      }
      return /*#__PURE__*/React.createElement(View, {
        style: style.fieldContainer
      }, /*#__PURE__*/React.createElement(Text, {
        style: style.attributeTitle
      }, `\u2022`), item instanceof Attribute && /*#__PURE__*/React.createElement(AttributeItem, {
        style: style.attributeTitle,
        item: item
      }), item instanceof Predicate && /*#__PURE__*/React.createElement(PredicateItem, {
        item: parsedPredicate,
        style: style.attributeTitle,
        onChangeValue: (name, value) => {
          onChangeValue(data.schema, item.label || name, name, value);
        }
      }));
    }
  }));
};
const ProofRequestDetails = _ref6 => {
  let {
    route,
    navigation
  } = _ref6;
  const {
    ColorPallet,
    TextTheme
  } = useTheme();
  const [store] = useStore();
  const {
    t
  } = useTranslation();
  const {
    i18n
  } = useTranslation();
  const {
    OCABundleResolver
  } = useConfiguration();
  const {
    agent
  } = useAgent();
  if (!agent) {
    throw new Error('Unable to fetch agent from AFJ');
  }
  const style = StyleSheet.create({
    container: {
      flexGrow: 1,
      backgroundColor: ColorPallet.brand.primaryBackground,
      padding: 16
    },
    header: {
      marginTop: 12,
      marginBottom: 36
    },
    title: {
      color: TextTheme.title.color,
      fontSize: 28,
      fontWeight: 'bold'
    },
    description: {
      marginTop: 10,
      color: TextTheme.title.color,
      fontSize: 20
    },
    footerButton: {
      marginTop: 'auto',
      marginBottom: 10
    }
  });
  const {
    templateId,
    connectionId
  } = route === null || route === void 0 ? void 0 : route.params;
  const [meta, setMeta] = useState(undefined);
  const [attributes, setAttributes] = useState(undefined);
  const [customPredicateValues, setCustomPredicateValues] = useState({});
  const [invalidPredicate, setInvalidPredicate] = useState(undefined);
  const template = useTemplate(templateId);
  useEffect(() => {
    if (!template) {
      return;
    }
    const attributes = template.payload.type === ProofRequestType.AnonCreds ? template.payload.data : [];
    OCABundleResolver.resolve({
      identifiers: {
        templateId
      },
      language: i18n.language
    }).then(bundle => {
      const metaOverlay = (bundle === null || bundle === void 0 ? void 0 : bundle.metaOverlay) || new MetaOverlay({
        capture_base: '',
        type: OverlayType.Meta10,
        name: template.name,
        description: template.description,
        language: i18n.language,
        credential_help_text: '',
        credential_support_url: '',
        issuer: '',
        issuer_description: '',
        issuer_url: ''
      });
      setMeta(metaOverlay);
      setAttributes(attributes);
    });
  }, [templateId, template]);
  const onlyNumberRegex = /^\d+$/;
  const onChangeValue = useCallback((schema, label, name, value) => {
    if (!onlyNumberRegex.test(value)) {
      setInvalidPredicate({
        visible: true,
        predicate: label
      });
      return;
    }
    setInvalidPredicate(undefined);
    setCustomPredicateValues(prev => ({
      ...prev,
      [schema]: {
        ...(prev[schema] || {}),
        [name]: parseInt(value)
      }
    }));
  }, [setCustomPredicateValues, setInvalidPredicate]);
  const useProofRequest = useCallback(async () => {
    if (!template) {
      return;
    }
    if (invalidPredicate) {
      setInvalidPredicate({
        visible: true,
        predicate: invalidPredicate.predicate
      });
      return;
    }
    if (connectionId) {
      var _navigation$getParent;
      // Send to specific contact and redirect to the chat with him
      sendProofRequest(agent, template, connectionId, customPredicateValues).then(result => {
        if (result !== null && result !== void 0 && result.proofRecord) {
          linkProofWithTemplate(agent, result.proofRecord, templateId);
        }
      });
      (_navigation$getParent = navigation.getParent()) === null || _navigation$getParent === void 0 ? void 0 : _navigation$getParent.navigate(Screens.Chat, {
        connectionId
      });
    } else {
      // Else redirect to the screen with connectionless request
      navigation.navigate(Screens.ProofRequesting, {
        templateId,
        predicateValues: customPredicateValues
      });
    }
  }, [agent, template, templateId, connectionId, customPredicateValues, invalidPredicate]);
  const showTemplateUsageHistory = useCallback(async () => {
    navigation.navigate(Screens.ProofRequestUsageHistory, {
      templateId
    });
  }, [navigation, templateId]);
  const Header = () => {
    return /*#__PURE__*/React.createElement(View, {
      style: style.header
    }, /*#__PURE__*/React.createElement(Text, {
      style: style.title
    }, meta === null || meta === void 0 ? void 0 : meta.name), /*#__PURE__*/React.createElement(Text, {
      style: style.description
    }, meta === null || meta === void 0 ? void 0 : meta.description));
  };
  const Footer = () => {
    return /*#__PURE__*/React.createElement(View, null, /*#__PURE__*/React.createElement(View, {
      style: style.footerButton
    }, /*#__PURE__*/React.createElement(Button, {
      title: connectionId ? t('Verifier.SendThisProofRequest') : t('Verifier.UseProofRequest'),
      accessibilityLabel: connectionId ? t('Verifier.SendThisProofRequest') : t('Verifier.UseProofRequest'),
      testID: connectionId ? testIdWithKey('SendThisProofRequest') : testIdWithKey('UseProofRequest'),
      buttonType: ButtonType.Primary,
      onPress: () => useProofRequest()
    })), store.preferences.useDataRetention && /*#__PURE__*/React.createElement(View, {
      style: style.footerButton
    }, /*#__PURE__*/React.createElement(Button, {
      title: t('Verifier.ShowTemplateUsageHistory'),
      accessibilityLabel: t('Verifier.ShowTemplateUsageHistory'),
      testID: testIdWithKey('ShowTemplateUsageHistory'),
      buttonType: ButtonType.Secondary,
      onPress: () => showTemplateUsageHistory()
    })));
  };
  return /*#__PURE__*/React.createElement(SafeAreaView, {
    style: style.container,
    edges: ['left', 'right']
  }, (invalidPredicate === null || invalidPredicate === void 0 ? void 0 : invalidPredicate.visible) && /*#__PURE__*/React.createElement(AlertModal, {
    title: t('Verifier.InvalidPredicateValueTitle', {
      predicate: invalidPredicate.predicate
    }),
    message: t('Verifier.InvalidPredicateValueDetails'),
    submit: () => setInvalidPredicate({
      visible: false,
      predicate: invalidPredicate.predicate
    })
  }), /*#__PURE__*/React.createElement(FlatList, {
    ListHeaderComponent: Header,
    ListFooterComponent: Footer,
    style: {
      backgroundColor: ColorPallet.brand.primaryBackground
    },
    data: attributes,
    keyExtractor: records => records.schema,
    renderItem: _ref7 => {
      let {
        item
      } = _ref7;
      return /*#__PURE__*/React.createElement(ProofRequestAttributesCard, {
        data: item,
        onChangeValue: onChangeValue
      });
    },
    ListFooterComponentStyle: {
      flexGrow: 1,
      justifyContent: 'flex-end'
    },
    contentContainerStyle: {
      flexGrow: 1
    }
  }));
};
export default ProofRequestDetails;
//# sourceMappingURL=ProofRequestDetails.js.map