/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

define([
  'ko',
  'underscore',
  'Magento_Ui/js/form/form',
  'Magento_Customer/js/model/customer',
  'Magento_Customer/js/model/address-list',
  'Magento_Checkout/js/model/quote',
  'Magento_Checkout/js/action/create-billing-address',
  'Magento_Checkout/js/action/select-billing-address',
  'Magento_Checkout/js/checkout-data',
  'Magento_Checkout/js/model/checkout-data-resolver',
  'Magento_Customer/js/customer-data',
  'Magento_Checkout/js/action/set-billing-address',
  'Magento_Ui/js/model/messageList',
  'mage/translate',
  'Magento_Checkout/js/model/billing-address-postcode-validator'
], function (
  ko,
  _,
  Component,
  customer,
  addressList,
  quote,
  createBillingAddress,
  selectBillingAddress,
  checkoutData,
  checkoutDataResolver,
  customerData,
  setBillingAddressAction,
  globalMessageList,
  $t,
  billingAddressPostcodeValidator
) {
  'use strict'

  var lastSelectedBillingAddress = null,
    countryData = customerData.get('directory-data'),
    addressOptions = addressList().filter(function (address) {
      return address.getType() === 'customer-address'
    })

  return Component.extend({
    defaults: {
      template: 'Magento_Checkout/billing-address',
      actionsTemplate: 'Magento_Checkout/billing-address/actions',
      formTemplate: 'Magento_Checkout/billing-address/form',
      detailsTemplate: 'Afd_Pce/billing-address/details',
      links: {
        isAddressFormVisible:
          '${$.billingAddressListProvider}:isNewAddressSelected'
      }
    },
    currentBillingAddress: quote.billingAddress,
    customerHasAddresses: addressOptions.length > 0,

    /**
     * Init component
     */
    initialize: function () {
      this._super()
      quote.paymentMethod.subscribe(function () {
        checkoutDataResolver.resolveBillingAddress()
      }, this)
      billingAddressPostcodeValidator.initFields(
        this.get('name') + '.form-fields'
      )
    },

    /**
     * @return {exports.initObservable}
     */
    initObservable: function () {
      this._super().observe({
        selectedAddress: null,
        isAddressDetailsVisible: quote.billingAddress() != null,
        isAddressFormVisible: !customer.isLoggedIn() || !addressOptions.length,
        isAddressSameAsShipping: false,
        saveInAddressBook: 1
      })

      quote.billingAddress.subscribe(function (newAddress) {
        if (quote.isVirtual()) {
          this.isAddressSameAsShipping(false)
        } else {
          this.isAddressSameAsShipping(
            newAddress != null &&
              newAddress.getCacheKey() == quote.shippingAddress().getCacheKey()
          )
        }

        if (newAddress != null && newAddress.saveInAddressBook !== undefined) {
          this.saveInAddressBook(newAddress.saveInAddressBook)
        } else {
          this.saveInAddressBook(1)
        }
        this.isAddressDetailsVisible(true)
      }, this)

      return this
    },

    canUseShippingAddress: ko.computed(function () {
      return (
        !quote.isVirtual() &&
        quote.shippingAddress() &&
        quote.shippingAddress().canUseForBilling()
      )
    }),

    /**
     * @param {Object} address
     * @return {*}
     */
    addressOptionsText: function (address) {
      return address.getAddressInline()
    },

    /**
     * @return {Boolean}
     */
    useShippingAddress: function () {
      if (this.isAddressSameAsShipping()) {
        selectBillingAddress(quote.shippingAddress())

        this.updateAddresses()
        this.isAddressDetailsVisible(true)
      } else {
        lastSelectedBillingAddress = quote.billingAddress()
        quote.billingAddress(null)
        this.isAddressDetailsVisible(false)
      }
      checkoutData.setSelectedBillingAddress(null)

      return true
    },

    /**
     * Update address action
     */
    updateAddress: function () {
      var addressData, newBillingAddress

      if (this.selectedAddress() && !this.isAddressFormVisible()) {
        selectBillingAddress(this.selectedAddress())
        checkoutData.setSelectedBillingAddress(this.selectedAddress().getKey())
      } else {
        this.source.set('params.invalid', false)
        this.source.trigger(this.dataScopePrefix + '.data.validate')

        if (this.source.get(this.dataScopePrefix + '.custom_attributes')) {
          this.source.trigger(
            this.dataScopePrefix + '.custom_attributes.data.validate'
          )
        }

        if (!this.source.get('params.invalid')) {
          addressData = this.source.get(this.dataScopePrefix)

          if (customer.isLoggedIn() && !this.customerHasAddresses) {
            this.saveInAddressBook(1)
          }
          addressData['save_in_address_book'] = this.saveInAddressBook() ? 1 : 0
          newBillingAddress = createBillingAddress(addressData)

          // New address must be selected as a billing address
          selectBillingAddress(newBillingAddress)
          checkoutData.setSelectedBillingAddress(newBillingAddress.getKey())
          checkoutData.setNewCustomerBillingAddress(addressData)
        }
      }
      this.updateAddresses()
    },

    /**
     * Edit address action
     */
    editAddress: function () {
      lastSelectedBillingAddress = quote.billingAddress()
      quote.billingAddress(null)
      this.isAddressDetailsVisible(false)
    },

    /**
     * Cancel address edit action
     */
    cancelAddressEdit: function () {
      this.restoreBillingAddress()

      if (quote.billingAddress()) {
        // restore 'Same As Shipping' checkbox state
        this.isAddressSameAsShipping(
          quote.billingAddress() != null &&
            quote.billingAddress().getCacheKey() ==
              quote.shippingAddress().getCacheKey() &&
            !quote.isVirtual()
        )
        this.isAddressDetailsVisible(true)
      }
    },

    /**
     * Manage cancel button visibility
     */
    canUseCancelBillingAddress: ko.computed(function () {
      return quote.billingAddress() || lastSelectedBillingAddress
    }),

    /**
     * Restore billing address
     */
    restoreBillingAddress: function () {
      if (lastSelectedBillingAddress != null) {
        selectBillingAddress(lastSelectedBillingAddress)
      }
    },

    /**
     * @param {Number} countryId
     * @return {*}
     */
    getCountryName: function (countryId) {
      return countryData()[countryId] != undefined
        ? countryData()[countryId].name
        : ''
    },

    /**
     * Trigger action to update shipping and billing addresses
     */
    updateAddresses: function () {
      if (
        window.checkoutConfig.reloadOnBillingAddress ||
        !window.checkoutConfig.displayBillingOnPaymentMethod
      ) {
        setBillingAddressAction(globalMessageList)
      }
    },

    /**
     * Get code
     * @param {Object} parent
     * @returns {String}
     */
    getCode: function (parent) {
      return _.isFunction(parent.getCode) ? parent.getCode() : 'shared'
    }
  })
})
