import { existsSync } from 'fs';
import { CarrierAppDefinition } from './carrier-app-definition';
import { CarrierAppMetadataSchema } from './metadata';
import { isDataValidationError, validateRatingData } from './native-rating-data-validator';
import { AppDeployment } from '@shipengine/connect-runtime';

// This creates an object that is only used by the Connect CLI
export const buildAppDeployment = (definition: CarrierAppDefinition): AppDeployment => {
  return {
    id: definition.Metadata.Id,
    getSupportedCountries: () => {
      const countries: (string | undefined)[] = [];
      const rootCountries = definition.Metadata.Carriers.flatMap((c) =>
        c.DefaultSupportedCountries?.flatMap((sc) => sc.FromCountry),
      );
      const serviceCountries = definition.Metadata.Carriers.flatMap((c) =>
        c.ShippingServices?.flatMap((s) => s.SupportedCountries).flatMap((sc) => sc?.FromCountry),
      );
      countries.push(...rootCountries);
      countries.push(...serviceCountries);
      return [...new Set(countries)].filter((c) => c !== undefined) as string[];
    },
    validate: () => {
      const results = CarrierAppMetadataSchema.validate(definition.Metadata, {
        allowUnknown: true,
        abortEarly: false,
      });
      if (results.error) {
        return results.error.details.map((detail) => `${detail.message}`);
      }

      const nativeRatingCarriers = definition.Metadata.Carriers.filter(
        (carrier) =>
          carrier.NativeRating &&
          carrier.NativeRating.Path &&
          existsSync(carrier.NativeRating.Path),
      );

      const validationErrors = nativeRatingCarriers
        .map(validateRatingData)
        .filter(isDataValidationError)
        .flat();
      if (validationErrors.length > 0) {
        return validationErrors.map(
          (error) => `${error.message} \n Duplicate Keys: ${error.duplicateKeys?.join(', ')}`,
        );
      }
    },
  };
};
