import { validation } from '../utils/validation'
import { REGEX_PHONE } from '../utils/regex'
import type { GenericResponse, GenericResponseItems, UserCart } from '~/types'
import type {
  AddressesList,
  CheckoutAddress,
  CheckoutOrder,
  Payment,
  UserAddressOfficial,
} from '~/types/checkout'
import type { CartProduct } from '~/types/product'

export const useCheckoutStore = defineStore('checkoutStore', () => {
  const { $toast } = useNuxtApp()
  const menuStore = useMenuStore()

  const selectedIso = ref(menuStore.selectedCountry)

  const vLegal = ref(false)
  const vTerms = ref(false)
  const vNote = ref('')
  const legalValidation = ref(false)
  const termsValidation = ref(false)
  const totalNumberOfProducts = ref(0)

  // get address list
  const addressesList = ref<AddressesList[]>()
  const activeAddress = ref<AddressesList | null>()
  async function getAddressList() {
    try {
      const { data } = await useMyFetch<GenericResponse<AddressesList[]>>(
        `/api/restricted/user/addresses`,
        {
          headers: {
            'Content-Type': 'application/json',
          },
          onErrorOccured: async (_, status) => {
            throw createError({
              statusCode: status,
              statusMessage: `HTTP error: ${status}`,
            })
          },
        },
      )

      addressesList.value = data
      activeAddress.value = addressesList.value[0]
    }
    catch (error) {
      console.error('restrictedAddress error:', error)
    }
  }

  // get user data
  const userName = ref('')
  const lastName = ref('')
  const address = ref('')
  const postCode = ref('')
  const city = ref('')
  const country = ref('')
  const phoneNumber = ref('')
  const accountPhoneNumber = ref('')
  async function getUserData() {
    try {
      const { data } = await useMyFetch<GenericResponse<UserAddressOfficial>>(
        `/api/restricted/user/address/official`,
        {
          headers: {
            'Content-Type': 'application/json',
          },
          onErrorOccured: async (_, status) => {
            throw createError({
              statusCode: status,
              statusMessage: `HTTP error: ${status}`,
            })
          },
        },
      )

      userName.value = data.address.name
      lastName.value = data.address.surname
      address.value = data.address.street
      postCode.value = data.address.postcode
      city.value = data.address.city
      country.value = data.address.country.country_lang[0].name
    }
    catch (error) {
      console.error('getUserData error:', error)
    }
  }

  // upload new address
  const vNewAddressName = ref('')
  const vNewAddressSurname = ref('')
  const vNewAddressAddress = ref('')
  const vNewAddressCode = ref('')
  const vNewAddressCity = ref('')
  const vNewAddressCountry = ref()
  const vUseAccountPhoneNumber = ref(false)
  const isOpen = ref<boolean>(false)
  async function uploadAddress() {
    try {
      const res = await useMyFetch<GenericResponse<object>>(
        `/api/restricted/user/address`,
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            address: {
              city: vNewAddressCity.value,
              country_iso: vNewAddressCountry.value.iso_code,
              name: vNewAddressName.value,
              postcode: vNewAddressCode.value,
              street: vNewAddressAddress.value,
              surname: vNewAddressSurname.value,
            },
          }),
          onErrorOccured: async (_, status) => {
            throw createError({
              statusCode: status,
              statusMessage: `HTTP error: ${status}`,
            })
          },
        },
      )

      if (res.status === 200) {
        $toast.success('Address successfully added', {
          autoClose: 5000,
          dangerouslyHTMLString: true,
        })
        isOpen.value = false
        getAddressList()
      }
      else {
        $toast.error('Failed to add address. Please try again.', {
          autoClose: 5000,
          dangerouslyHTMLString: true,
        })
      }
    }
    catch (error) {
      console.error('uploadAddress error:', error)
    }
  }

  const currentPrefix = ref<string | number>(
    menuStore.selectedCountry.call_prefix,
  )
  const changePrefix = (item: string) => {
    currentPrefix.value = item
  }
  const phoneValidation = ref<boolean | null>(null)

  // send checkout form
  const userStore = useUserStore()
  async function sendForm() {
    const phoneNum = vUseAccountPhoneNumber.value
      ? accountPhoneNumber.value
      : `${currentPrefix.value}${phoneNumber.value}`.replaceAll(' ', '').trim()
    // if (vUseAccountPhoneNumber.value) {
    //   phoneNum = phoneNumber.value;
    // }

    phoneValidation.value = validation(phoneNum, 1, 49, REGEX_PHONE)
    if (!phoneValidation.value && !vUseAccountPhoneNumber.value) {
      return
    }

    try {
      const res = await useMyFetch<GenericResponse<object>>(
        `/api/restricted/cart/checkout/delivery`,
        {
          method: 'PUT',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            address: {
              city: activeAddress.value?.address.city,
              country_iso: activeAddress.value?.address.country_iso,
              name: activeAddress.value?.address.name,
              postcode: activeAddress.value?.address.postcode,
              street: activeAddress.value?.address.street,
              surname: activeAddress.value?.address.surname,
            },
            phone_number: phoneNum,
            email: userStore.fullUserData?.email,
          }),
          onErrorOccured: async (_, status) => {
            throw createError({
              statusCode: status,
              statusMessage: `HTTP error: ${status}`,
            })
          },
        },
      )

      console.log(res)

      if (res.status === 200) {
        $toast.success('Form successfully sent', {
          autoClose: 5000,
          dangerouslyHTMLString: true,
        })
        menuStore.navigateToItem(
          menuStore.menuItems?.find(item => item.id === 13),
        )
      }
      else {
        $toast.error('Failed to send form. Please try again.', {
          autoClose: 5000,
          dangerouslyHTMLString: true,
        })
      }
    }
    catch (error) {
      console.error('uploadAddress error:', error)
    }
  }

  // get checkout
  async function getCheckout() {
    try {
      await useMyFetch<GenericResponse<object>>(
        `/api/restricted/cart/checkout`,
        {
          method: 'PUT',
          headers: {
            'Content-Type': 'application/json',
          },
          onErrorOccured: async (_, status) => {
            throw createError({
              statusCode: status,
              statusMessage: `HTTP error: ${status}`,
            })
          },
        },
      )
    }
    catch (error) {
      console.error('uploadAddress error:', error)
    }
  }

  // get user cart
  const products = ref<CartProduct[]>()
  const fullPrice = ref()
  const fullProductsPrice = ref()
  async function getUserCart() {
    try {
      const { data } = await useMyFetch<GenericResponse<UserCart>>(
        `/api/public/user/cart`,
        {
          headers: {
            'Content-Type': 'application/json',
          },
          onErrorOccured: async (_, status) => {
            throw createError({
              statusCode: status,
              statusMessage: `HTTP error: ${status}`,
            })
          },
        },
      )

      totalNumberOfProducts.value = 0
      if (data.cart_items && Array.isArray(data.cart_items)) {
        for (const item of data.cart_items) {
          totalNumberOfProducts.value = totalNumberOfProducts.value + item.quantity
        }
      }

      products.value = data.cart_items
      fullPrice.value = data.total_value
      fullProductsPrice.value = data.total_value
      fullPrice.value = Number(fullPrice.value) + Number(shippingPrice.value)
    }
    catch (error) {
      console.error('getUserCart error:', error)
    }
  }

  // get delivery options
  interface DeliveryOptionItem {
    country_iso: string
    country_name: string
    delivery_supplier_id: number
    delivery_supplier_name: string
    id: number
    shippment_price: string
  }

  const deliveryOption = ref<DeliveryOptionItem[]>([])
  const currentDelivery = ref<DeliveryOptionItem | null>(null)
  const shippingPrice = ref<number>(0)

  async function getDeliveryOptions() {
    try {
      const { data } = await useMyFetch<GenericResponseItems<DeliveryOptionItem[]>>(
        `/api/restricted/cart/checkout/delivery-options`,
        {
          headers: {
            'Content-Type': 'application/json',
          },
          onErrorOccured: async (_, status) => {
            throw createError({
              statusCode: status,
              statusMessage: `HTTP error: ${status}`,
            })
          },
        },
      )

      if (data.items && data.items.length > 0) {
        deliveryOption.value = data.items
        currentDelivery.value = data.items[0]
        shippingPrice.value = Number(data.items[0].shippment_price)
        fullPrice.value += shippingPrice.value
      }
    }
    catch (error) {
      console.error('getDeliveryOptions error:', error)
    }
  }

  const setCurrentDelivery = (item: DeliveryOptionItem) => {
    shippingPrice.value = Number(item.shippment_price)
    currentDelivery.value = item
    fullPrice.value = Number(fullPrice.value) + Number(shippingPrice.value)
  }

  const defaultAddress = ref<CheckoutAddress | undefined>()

  async function getDefAddress() {
    try {
      const { data } = await useMyFetch<GenericResponse<{ addresses: Address[] }>>(
        `/api/public/user`,
        {
          headers: {
            'Content-Type': 'application/json',
          },
          onErrorOccured: async (_, status) => {
            throw createError({
              statusCode: status,
              statusMessage: `HTTP error: ${status}`,
            })
          },
        },
      )

      defaultAddress.value = data.addresses.find(
        el => el.is_default === true || el.is_default === 'true',
      )
    }
    catch (error) {
      console.error('getUserCart error:', error)
    }
  }

  // get bank data
  const paymentMethods = ref([] as Payment[])
  const fullAddress = ref<Address>()
  const currentPayment = ref<Payment | null>()
  async function getBankAccount() {
    try {
      const { data } = await useMyFetch<GenericResponse<Payment[]>>(
        `/api/restricted/suitable-bank-accounts/${menuStore.selectedCurrency.iso_code}/${fullAddress.value?.country_iso}`,
        {
          headers: {
            'Content-Type': 'application/json',
          },
          onErrorOccured: async (_, status) => {
            throw createError({
              statusCode: status,
              statusMessage: `HTTP error: ${status}`,
            })
          },
        },
      )

      paymentMethods.value = data
      currentPayment.value = data[0]
    }
    catch (error) {
      console.error('getUserCart error:', error)
    }
  }

  // get order (summary)
  async function getOrder() {
    try {
      const { data } = await useMyFetch<GenericResponse<CheckoutOrder>>(
        `/api/restricted/cart/checkout/order`,
        {
          headers: {
            'Content-Type': 'application/json',
          },
          onErrorOccured: async (_, status) => {
            throw createError({
              statusCode: status,
              statusMessage: `HTTP error: ${status}`,
            })
          },
        },
      )

      fullAddress.value = data.delivery_details.address
    }
    catch (error) {
      console.error('getOrder error:', error)
    }
  }

  async function setNewAddress(indexItem: number) {
    currentPayment.value = paymentMethods.value.find(
      (item, index) => indexItem === index,
    )
  }

  // send summary form
  async function sendSummaryForm() {
    legalValidation.value = !vLegal.value
    termsValidation.value = !vTerms.value

    if (!vTerms.value && !vLegal.value) {
      return
    }

    try {
      await useMyFetch<GenericResponse<object>>(
        `/api/restricted/cart/checkout/delivery`,
        {
          method: 'PUT',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            accept_general_conditions: true,
            accept_long_purchase: true,
            address: fullAddress.value,
            delivery_option_id: currentDelivery.value?.id,
            note: vNote.value,
          }),
          onErrorOccured: async (_, status) => {
            throw createError({
              statusCode: status,
              statusMessage: `HTTP error: ${status}`,
            })
          },
        },
      )

      await putCheckoutBankAccount()
      await markOrder()
      await getUserCart()
    }
    catch (error) {
      console.error('uploadAddress error:', error)
    }
  }

  // put checkout bank-account
  async function putCheckoutBankAccount() {
    try {
      await useMyFetch<GenericResponse<object>>(
        `/api/restricted/cart/checkout/bank-account/${currentPayment.value?.id}`,
        {
          method: 'PUT',
          headers: {
            'Content-Type': 'application/json',
          },
          onErrorOccured: async (_, status) => {
            throw createError({
              statusCode: status,
              statusMessage: `HTTP error: ${status}`,
            })
          },
        },
      )
    }
    catch (error) {
      console.error('uploadAddress error:', error)
    }
  }

  const modalMadeOrder = ref(false)
  async function markOrder() {
    try {
      const res = await useMyFetch<GenericResponse<object>>(
        `/api/restricted/cart/checkout/order`,
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          onErrorOccured: async (_, status) => {
            throw createError({
              statusCode: status,
              statusMessage: `HTTP error: ${status}`,
            })
          },
        },
      )

      if (res.status === 200 || res.status === 201) {
        $toast.success('Address successfully added', {
          autoClose: 5000,
          dangerouslyHTMLString: true,
        })
        modalMadeOrder.value = true
      }
      else {
        $toast.error('Failed to add address. Please try again.', {
          autoClose: 5000,
          dangerouslyHTMLString: true,
        })
      }
      // window.location.href = `/golden-panel/my-purchases/${res._data?.data.id}`;
    }
    catch (error) {
      console.error('uploadAddress error:', error)
    }
  }
  return {
    addressesList,
    activeAddress,
    isOpen,
    selectedIso,
    phoneValidation,

    userName,
    lastName,
    address,
    postCode,
    city,
    country,
    phoneNumber,
    accountPhoneNumber,
    vUseAccountPhoneNumber,

    currentPrefix,
    vNewAddressName,
    vNewAddressSurname,
    vNewAddressAddress,
    vNewAddressCode,
    vNewAddressCity,
    vNewAddressCountry,

    products,
    fullPrice,
    fullProductsPrice,
    deliveryOption,
    currentDelivery,
    shippingPrice,
    defaultAddress,
    paymentMethods,
    currentPayment,
    fullAddress,
    totalNumberOfProducts,

    vLegal,
    vTerms,
    vNote,
    legalValidation,
    termsValidation,
    modalMadeOrder,

    changePrefix,
    getCheckout,
    getAddressList,
    getUserData,
    uploadAddress,
    sendForm,
    getUserCart,
    getDeliveryOptions,
    getDefAddress,
    setCurrentDelivery,
    getBankAccount,
    getOrder,
    setNewAddress,
    sendSummaryForm,
  }
})
