import { Injectable, Logger } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { AxiosError, AxiosInstance } from 'axios'; import { createOutboundAxiosInstance } from '../../common/helpers/http-client.helper'; import { FanavaranConfig } from '../../config/configuration'; import { FanavaranAuthService } from './fanavaran-auth.service'; import { FanavaranInsuranceLineId, FanavaranPolicySummary, ThirdPartyCarFinancialClaimPayload, } from './fanavaran.types'; @Injectable() export class FanavaranApiService { private readonly logger = new Logger(FanavaranApiService.name); private readonly httpClient: AxiosInstance; private readonly config: FanavaranConfig; constructor( configService: ConfigService, private readonly authService: FanavaranAuthService, ) { this.config = configService.get('fanavaran')!; this.httpClient = createOutboundAxiosInstance({ baseURL: this.config.baseUrl, timeout: this.config.timeout, headers: { 'Content-Type': 'application/json', }, }); } async inquiryLatestPolicy( nationalCode: string, insuranceLineId: FanavaranInsuranceLineId = FanavaranInsuranceLineId.THIRD_PARTY, ): Promise { const authenticationToken = await this.authService.getAuthenticationToken(); const response = await this.httpClient.get( '/api/BimeApi/v2.0/common/Policies/inquiry-my-policies', { params: { InsuranceLineId: insuranceLineId, NationalCode: nationalCode, }, headers: this.buildCommonHeaders(authenticationToken, this.config.policyInquiryLocation), }, ); const policies = Array.isArray(response.data) ? response.data : []; if (policies.length === 0) { throw new Error( `No Fanavaran policies found for nationalCode=${nationalCode}, insuranceLineId=${insuranceLineId}`, ); } const latest = this.pickLatestPolicy(policies); this.logger.log( `Fanavaran policy selected | nationalCode=${nationalCode} | policyId=${latest.PolicyId} | issuDate=${latest.IssuDate}`, ); return latest; } async submitThirdPartyCarFinancialClaim( payload: ThirdPartyCarFinancialClaimPayload, ): Promise { const authenticationToken = await this.authService.getAuthenticationToken(); try { const response = await this.httpClient.post( '/api/BimeApi/v2.0/car/third-party-car-financial-claims', payload, { headers: this.buildCommonHeaders(authenticationToken, this.config.claimSubmitLocation), }, ); return response.data; } catch (error) { throw this.formatApiError(error); } } pickLatestPolicy(policies: FanavaranPolicySummary[]): FanavaranPolicySummary { return [...policies].sort((left, right) => { const dateCompare = right.IssuDate.localeCompare(left.IssuDate); if (dateCompare !== 0) { return dateCompare; } return right.PolicyId - left.PolicyId; })[0]; } private buildCommonHeaders( authenticationToken: string, location: number, ): Record { return { authenticationToken, CorpId: this.config.corpId, ContractId: this.config.contractId, Location: location, }; } private formatApiError(error: unknown): Error { if (!(error instanceof AxiosError)) { return error instanceof Error ? error : new Error(String(error)); } const status = error.response?.status; const body = typeof error.response?.data === 'string' ? error.response.data : JSON.stringify(error.response?.data ?? {}); return new Error( `Fanavaran API request failed${status ? ` (${status})` : ''}: ${error.message} | body=${body}`, ); } }