import { TalerFormAttributes, TranslatedString } from "@gnu-taler/taler-util";
import { intervalToDuration, isFuture, isValid, parse } from "date-fns";
import {
  DoubleColumnFormDesign,
  FormMetadata,
  InternationalizationAPI,
} from "../../index.browser.js";
import {
  countryNameList,
  countryNationalityList,
  drilldownGlsIndustries,
  germanBusinessTypes,
} from "../../utils/select-ui-lists.js";

export const form_gls_merchant_onboarding = (
  i18n: InternationalizationAPI,
): FormMetadata => ({
  config: gls_merchant_onboarding(i18n, {}),
  id: "gls-merchant-onboarding",
  label: "GLS Merchant Onboarding",
  version: 1,
});

function validateDateOfBirth(
  i18n: InternationalizationAPI,
  text: string,
  _form: any,
): TranslatedString | undefined {
  // Date is stored as ISO timestamp
  const time = parse(text, "yyyy-MM-dd", new Date());
  if (!isValid(time)) {
    return i18n.str`invalid format`;
  }
  if (isFuture(time)) {
    return i18n.str`it can't be in the future`;
  }
  const { years } = intervalToDuration({
    start: time,
    end: new Date(),
  });
  if (years && years > 120) {
    return i18n.str`it can't be greater than 120 years`;
  }
  return undefined;
}

function validateFoundingDate(
  i18n: InternationalizationAPI,
  text: string,
  _form: any,
): TranslatedString | undefined {
  // Date is stored as ISO timestamp
  const time = parse(text, "yyyy-MM-dd", new Date());
  if (!isValid(time)) {
    return i18n.str`invalid format`;
  }
  if (isFuture(time)) {
    return i18n.str`it can't be in the future`;
  }
  const { years } = intervalToDuration({
    start: time,
    end: new Date(),
  });
  if (years && years > 120) {
    return i18n.str`it can't be greater than 120 years`;
  }
  return undefined;
}

function validateEmail(
  i18n: InternationalizationAPI,
  text: string,
  _form: any,
): TranslatedString | undefined {
  const re = /^\S+@\S+\.\S+$/;
  if (re.test(text)) {
    return undefined;
  }
  return i18n.str`Invalid e-mail address`;
}

function validatePhone(
  i18n: InternationalizationAPI,
  text: string,
  _form: any,
): TranslatedString | undefined {
  const re = /^[+]?([0-9]+[. ]*)+$/;
  if (re.test(text)) {
    return undefined;
  }
  return i18n.str`Invalid phone number`;
}

export function gls_merchant_onboarding(
  i18n: InternationalizationAPI,
  context?: any,
): DoubleColumnFormDesign {
  return {
    type: "double-column",
    title: "Merchant Onboarding Information",
    sections: [
      {
        title: i18n.str`Personal Details`,
        description: i18n.str`Personal details of the authorised representative.`,
        fields: [
          {
            id: TalerFormAttributes.PERSON_FIRST_NAMES,
            label: i18n.str`First name(s)`,
            help: i18n.str`As on your ID document`,
            type: "text",
            required: true,
          },
          {
            id: TalerFormAttributes.PERSON_LAST_NAME,
            label: i18n.str`Last name`,
            type: "text",
            required: true,
          },
          {
            id: TalerFormAttributes.DATE_OF_BIRTH,
            label: i18n.str`Date of birth`,
            type: "isoDateText",
            placeholder: "dd.MM.yyyy",
            pattern: "dd.MM.yyyy",
            required: true,
            validator: (text, form) => validateDateOfBirth(i18n, text, form),
          },
          {
            id: TalerFormAttributes.NATIONALITY,
            label: i18n.str`Nationality`,
            type: "selectOne",
            choices: countryNationalityList(i18n),
            required: true,
          },
          {
            id: TalerFormAttributes.CONTACT_PHONE,
            label: i18n.str`Phone number`,
            type: "text",
            required: true,
            validator: (text, form) => validatePhone(i18n, text, form),
          },
          {
            id: TalerFormAttributes.CONTACT_EMAIL,
            label: i18n.str`E-Mail`,
            type: "text",
            required: true,
            validator: (text, form) => validateEmail(i18n, text, form),
          },
        ],
      },
      {
        title: i18n.str`Company information`,
        fields: [
          {
            id: TalerFormAttributes.BUSINESS_DISPLAY_NAME,
            label: i18n.str`Name of the company`,
            type: "text",
            required: true,
          },
          {
            id: TalerFormAttributes.BUSINESS_TYPE,
            label: i18n.str`Legal form`,
            required: true,
            type: "selectOne",
            choices: germanBusinessTypes(i18n),
          },
          {
            id: TalerFormAttributes.BUSINESS_TYPE_OTHER,
            label: i18n.str`Legal form (free-form entry for other)`,
            hide(value, root) {
              return root[TalerFormAttributes.BUSINESS_TYPE] !== "OTHER";
            },
            required: true,
            type: "text",
          },
          {
            id: TalerFormAttributes.COMMERCIAL_REGISTER_NUMBER,
            label: i18n.str`Commercial register number`,
            type: "text",
            required: true,
          },
          {
            id: TalerFormAttributes.REGISTER_COURT_LOCATION,
            label: i18n.str`Seat of the register court`,
            type: "text",
            required: true,
          },
          {
            id: TalerFormAttributes.FOUNDING_DATE,
            label: i18n.str`Founding date`,
            type: "isoDateText",
            placeholder: "dd.MM.yyyy",
            pattern: "dd.MM.yyyy",
            required: true,
            validator: (text, form) => validateFoundingDate(i18n, text, form),
          },
          {
            id: TalerFormAttributes.BUSINESS_IS_NON_PROFIT,
            label: i18n.str`Is the company a non-profit organization?`,
            required: true,
            type: "choiceHorizontal",
            choices: [
              {
                label: "Yes",
                value: true,
              },
              {
                label: "No",
                value: false,
              },
            ],
          },
          {
            id: TalerFormAttributes.BUSINESS_INDUSTRY,
            label: i18n.str`Industry`,
            required: true,
            type: "drilldown",
            choices: drilldownGlsIndustries,
          },
        ],
      },
      {
        title: i18n.str`Company address`,
        fields: [
          {
            id: TalerFormAttributes.DOMICILE_ADDRESS,
            label: i18n.str`Address`,
            type: "textArea",
            required: true,
          },
          {
            id: TalerFormAttributes.ADDRESS_COUNTRY,
            label: i18n.str`Country`,
            type: "selectOne",
            choices: countryNameList(i18n),
            required: true,
          },
        ],
      },
      {
        title: i18n.str`Tax information`,
        fields: [
          {
            id: TalerFormAttributes.DE_BUSINESS_OR_TAX_ID,
            label: i18n.str`Business identification number or tax number`,
            type: "text",
            required: true,
          },
          {
            id: TalerFormAttributes.TAX_IS_USA_LAW,
            label: i18n.str`Was the company incorporated in the USA or under US law?`,
            required: true,
            type: "choiceHorizontal",
            choices: [
              {
                label: "Yes",
                value: true,
              },
              {
                label: "No",
                value: false,
              },
            ],
          },
          {
            id: TalerFormAttributes.TAX_IS_ACTIVE,
            label: i18n.str`Economically active or inactive?`,
            type: "choiceHorizontal",
            choices: [
              {
                label: "Active",
                value: "ACTIVE",
              },
              {
                label: "Inactive",
                value: "INACTIVE",
              },
            ],
            required: true,
          },
          {
            id: TalerFormAttributes.TAX_IS_DEDUCTED,
            label: i18n.str`Eligible for input tax deduction`,
            type: "choiceHorizontal",
            choices: [
              {
                label: "Yes",
                value: true,
              },
              {
                label: "No",
                value: false,
              },
            ],
            required: true,
          },
        ],
      },
      {
        title: i18n.str`Persons`,
        description: i18n.str`Please list all legal representatives, shareholders/partners, and authorized signatories.`,
        fields: [
          {
            id: TalerFormAttributes.BUSINESS_PERSONS,
            label: i18n.str`Legal representatives / shareholders / partners / authorized signatories`,
            type: "array",
            labelFieldId: TalerFormAttributes.PERSON_LAST_NAME,
            fields: [
              {
                id: TalerFormAttributes.PERSON_FIRST_NAMES,
                label: i18n.str`First name(s)`,
                type: "text",
                required: true,
              },
              {
                id: TalerFormAttributes.PERSON_LAST_NAME,
                label: i18n.str`Last name`,
                type: "text",
                required: true,
              },
              {
                id: TalerFormAttributes.DATE_OF_BIRTH,
                label: i18n.str`Date of birth`,
                type: "isoDateText",
                placeholder: "dd.MM.yyyy",
                pattern: "dd.MM.yyyy",
                required: true,
                validator: (text, form) =>
                  validateDateOfBirth(i18n, text, form),
              },
              {
                id: TalerFormAttributes.NATIONALITY,
                label: i18n.str`Nationality`,
                type: "selectOne",
                choices: countryNationalityList(i18n),
                required: true,
              },
              {
                id: TalerFormAttributes.REPRESENTATIVE_TYPE,
                label: i18n.str`Type of representative`,
                type: "choiceStacked",
                choices: [
                  {
                    label: "Shareholder (at least 25% of shares)",
                    value: "SHAREHOLDER_GT_25_PERCENT",
                  },
                  {
                    label: "Legal representative",
                    value: "LEGAL_REPRESENTATIVE",
                  },
                  {
                    label: "Authorized employee with account access",
                    value: "AUTHORIZED_EMPLOYEE",
                  },
                ],
              },
            ],
            required: true,
          },
        ],
      },
      {
        title: i18n.str`New Customer Identification`,
        fields: [
          {
            type: "caption",
            label: "Please complete the customer registration and identification for the authorized representative and other persons listed in this form.",
          },
          {
            type: "external-link",
            url: "https://kontoeroeffnung.gls.de/kundenanlage/gks-v",
            id: "none",
            label: "GLS Customer Registration",
          }
        ],
      },
    ],
  };
}
