import { ComponentType } from '@defra/forms-model';
import { ComponentCollection } from "./ComponentCollection.js";
import { FormComponent, isFormState } from "./FormComponent.js";
import { createLocationFieldValidator, getLocationFieldViewModel } from "./LocationFieldHelpers.js";
import { NumberField } from "./NumberField.js";
import { messageTemplate } from "../pageControllers/validationOptions.js";
import { convertToLanguageMessages } from "../../../utils/type-utils.js";

// British National Grid coordinate limits
const DEFAULT_EASTING_MIN = 0;
const DEFAULT_EASTING_MAX = 70000;
const DEFAULT_NORTHING_MIN = 0;
const DEFAULT_NORTHING_MAX = 1300000;
export class EastingNorthingField extends FormComponent {
  constructor(def, props) {
    super(def, props);
    const {
      name,
      options,
      schema
    } = def;
    const isRequired = options.required !== false;
    const eastingMin = schema?.easting?.min ?? DEFAULT_EASTING_MIN;
    const eastingMax = schema?.easting?.max ?? DEFAULT_EASTING_MAX;
    const northingMin = schema?.northing?.min ?? DEFAULT_NORTHING_MIN;
    const northingMax = schema?.northing?.max ?? DEFAULT_NORTHING_MAX;
    const customValidationMessages = convertToLanguageMessages({
      'any.required': messageTemplate.objectMissing,
      'number.base': messageTemplate.objectMissing,
      'number.min': `{{#label}} for ${this.title} must be between {{#limit}} and ${eastingMax}`,
      'number.max': `{{#label}} for ${this.title} must be between ${eastingMin} and {{#limit}}`,
      'number.precision': `{{#label}} for ${this.title} must be between 1 and 5 digits`,
      'number.integer': `{{#label}} for ${this.title} must be between 1 and 5 digits`,
      'number.unsafe': `{{#label}} for ${this.title} must be between 1 and 5 digits`
    });
    const northingValidationMessages = convertToLanguageMessages({
      'any.required': messageTemplate.objectMissing,
      'number.base': messageTemplate.objectMissing,
      'number.min': `{{#label}} for ${this.title} must be between {{#limit}} and ${northingMax}`,
      'number.max': `{{#label}} for ${this.title} must be between ${northingMin} and {{#limit}}`,
      'number.precision': `{{#label}} for ${this.title} must be between 1 and 7 digits`,
      'number.integer': `{{#label}} for ${this.title} must be between 1 and 7 digits`,
      'number.unsafe': `{{#label}} for ${this.title} must be between 1 and 7 digits`
    });
    this.collection = new ComponentCollection([{
      type: ComponentType.NumberField,
      name: `${name}__easting`,
      title: 'Easting',
      schema: {
        min: eastingMin,
        max: eastingMax,
        precision: 0
      },
      options: {
        required: isRequired,
        optionalText: true,
        classes: 'govuk-input--width-10',
        customValidationMessages
      }
    }, {
      type: ComponentType.NumberField,
      name: `${name}__northing`,
      title: 'Northing',
      schema: {
        min: northingMin,
        max: northingMax,
        precision: 0
      },
      options: {
        required: isRequired,
        optionalText: true,
        classes: 'govuk-input--width-10',
        customValidationMessages: northingValidationMessages
      }
    }], {
      ...props,
      parent: this
    }, {
      custom: getValidatorEastingNorthing(this),
      peers: [`${name}__easting`, `${name}__northing`]
    });
    this.options = options;
    this.formSchema = this.collection.formSchema;
    this.stateSchema = this.collection.stateSchema;
  }
  getFormValueFromState(state) {
    const value = super.getFormValueFromState(state);
    return EastingNorthingField.isEastingNorthing(value) ? value : undefined;
  }
  getDisplayStringFromFormValue(value) {
    if (!value) {
      return '';
    }

    // CYA page format: <<northingvalue, eastingvalue>>
    return `${value.northing}, ${value.easting}`;
  }
  getDisplayStringFromState(state) {
    const value = this.getFormValueFromState(state);
    return this.getDisplayStringFromFormValue(value);
  }
  getContextValueFromFormValue(value) {
    if (!value) {
      return null;
    }

    // Output format: Northing: <<entry>>\nEasting: <<entry>>
    return `Northing: ${value.northing}\nEasting: ${value.easting}`;
  }
  getContextValueFromState(state) {
    const value = this.getFormValueFromState(state);
    return this.getContextValueFromFormValue(value);
  }
  getViewModel(payload, errors) {
    const viewModel = super.getViewModel(payload, errors);
    return getLocationFieldViewModel(this, viewModel, payload, errors);
  }
  isState(value) {
    return EastingNorthingField.isEastingNorthing(value);
  }

  /**
   * For error preview page that shows all possible errors on a component
   */
  getAllPossibleErrors() {
    return EastingNorthingField.getAllPossibleErrors();
  }

  /**
   * Static version of getAllPossibleErrors that doesn't require a component instance.
   */
  static getAllPossibleErrors() {
    return {
      baseErrors: [{
        type: 'required',
        template: messageTemplate.required
      }, {
        type: 'eastingFormat',
        template: 'Easting for [short description] must be between 1 and 5 digits'
      }, {
        type: 'northingFormat',
        template: 'Northing for [short description] must be between 1 and 7 digits'
      }],
      advancedSettingsErrors: [{
        type: 'eastingMin',
        template: `Easting for [short description] must be between ${DEFAULT_EASTING_MIN} and ${DEFAULT_EASTING_MAX}`
      }, {
        type: 'eastingMax',
        template: `Easting for [short description] must be between ${DEFAULT_EASTING_MIN} and ${DEFAULT_EASTING_MAX}`
      }, {
        type: 'northingMin',
        template: `Northing for [short description] must be between ${DEFAULT_NORTHING_MIN} and ${DEFAULT_NORTHING_MAX}`
      }, {
        type: 'northingMax',
        template: `Northing for [short description] must be between ${DEFAULT_NORTHING_MIN} and ${DEFAULT_NORTHING_MAX}`
      }]
    };
  }
  static isEastingNorthing(value) {
    return isFormState(value) && NumberField.isNumber(value.easting) && NumberField.isNumber(value.northing);
  }
}
export function getValidatorEastingNorthing(component) {
  return createLocationFieldValidator(component);
}
//# sourceMappingURL=EastingNorthingField.js.map