import { createContext, useContext, useEffect, useState } from 'react';
import { ClaimFormat, SdJwtVcRecord, SdJwtVcRepository, W3cCredentialRecord, W3cCredentialRepository } from '@credo-ts/core';
import { useAgent } from '@credo-ts/react-hooks';
import { recordsAddedByType, recordsRemovedByType } from '@credo-ts/react-hooks/build/recordUtils';
import { TOKENS, useServices } from '../../../container-api';
const addRecord = (record, state) => {
  const newRecordsState = [...state.w3cCredentialRecords];
  newRecordsState.unshift(record);
  return {
    ...state,
    w3cCredentialRecords: newRecordsState
  };
};
const removeRecord = (record, state) => {
  const newRecordsState = [...state.w3cCredentialRecords];
  const index = newRecordsState.findIndex(r => r.id === record.id);
  if (index > -1) {
    newRecordsState.splice(index, 1);
  }
  return {
    ...state,
    w3cCredentialRecords: newRecordsState
  };
};
const defaultState = {
  openIDCredentialRecords: [],
  w3cCredentialRecords: [],
  sdJwtVcRecords: [],
  isLoading: true
};
const OpenIDCredentialRecordContext = /*#__PURE__*/createContext(null);
const isW3CCredentialRecord = record => {
  var _record$getTags;
  return ((_record$getTags = record.getTags()) === null || _record$getTags === void 0 ? void 0 : _record$getTags.claimFormat) === ClaimFormat.JwtVc;
};
const filterW3CCredentialsOnly = credentials => {
  return credentials.filter(r => isW3CCredentialRecord(r));
};

// eslint-disable-next-line react/prop-types
export const OpenIDCredentialRecordProvider = ({
  children
}) => {
  const [state, setState] = useState(defaultState);
  const {
    agent
  } = useAgent();
  const [logger] = useServices([TOKENS.UTIL_LOGGER]);
  function checkAgent() {
    if (!agent) {
      const error = 'Agent undefined!';
      logger.error(`[OpenIDCredentialRecordProvider] ${error}`);
      throw new Error(error);
    }
  }
  async function storeCredential(cred) {
    checkAgent();
    if (cred instanceof W3cCredentialRecord) {
      await (agent === null || agent === void 0 ? void 0 : agent.dependencyManager.resolve(W3cCredentialRepository).save(agent.context, cred));
    } else {
      await (agent === null || agent === void 0 ? void 0 : agent.dependencyManager.resolve(SdJwtVcRepository).save(agent.context, cred));
    }
  }
  async function deleteCredential(cred) {
    checkAgent();
    if (cred instanceof W3cCredentialRecord) {
      await (agent === null || agent === void 0 ? void 0 : agent.w3cCredentials.removeCredentialRecord(cred.id));
    } else if (cred instanceof SdJwtVcRecord) {
      await (agent === null || agent === void 0 ? void 0 : agent.sdJwtVc.deleteById(cred.id));
    }
  }
  useEffect(() => {
    var _agent$w3cCredentials;
    if (!agent) {
      return;
    }
    (_agent$w3cCredentials = agent.w3cCredentials) === null || _agent$w3cCredentials === void 0 || _agent$w3cCredentials.getAllCredentialRecords().then(w3cCredentialRecords => {
      setState(prev => ({
        ...prev,
        w3cCredentialRecords: filterW3CCredentialsOnly(w3cCredentialRecords),
        isLoading: false
      }));
    });
  }, [agent]);
  useEffect(() => {
    if (!state.isLoading && agent) {
      const credentialAdded$ = recordsAddedByType(agent, W3cCredentialRecord).subscribe(record => {
        //This handler will return ANY creds added to the wallet even DidComm
        //Sounds like a bug in the hooks package
        //This check will safe guard the flow untill a fix goes to the hooks
        if (isW3CCredentialRecord(record)) {
          setState(addRecord(record, state));
        }
      });
      const credentialRemoved$ = recordsRemovedByType(agent, W3cCredentialRecord).subscribe(record => {
        setState(removeRecord(record, state));
      });
      return () => {
        credentialAdded$.unsubscribe();
        credentialRemoved$.unsubscribe();
      };
    }
  }, [state, agent]);
  return /*#__PURE__*/React.createElement(OpenIDCredentialRecordContext.Provider, {
    value: {
      openIdState: state,
      storeCredential: storeCredential,
      removeCredential: deleteCredential
    }
  }, children);
};
export const useOpenIDCredentials = () => useContext(OpenIDCredentialRecordContext);
//# sourceMappingURL=OpenIDCredentialRecordProvider.js.map