"use client"

import React, { useEffect, useMemo, useState, useRef, useActionState } from "react"

import Input from "@modules/common/components/input"
import NativeSelect from "@modules/common/components/native-select"

import AccountInfo from "../account-info"
import { HttpTypes } from "@medusajs/types"
import { addCustomerAddress, updateCustomerAddress } from "@lib/data/customer"
import RajaOngkirAddressSelector from "@modules/checkout/components/rajaongkir-address-selector"

type MyInformationProps = {
  customer: HttpTypes.StoreCustomer
  regions: HttpTypes.StoreRegion[]
}

const ProfileBillingAddress: React.FC<MyInformationProps> = ({
  customer,
  regions,
}) => {
  const regionOptions = useMemo(() => {
    return (
      regions
        ?.map((region) => {
          return region.countries?.map((country) => ({
            value: country.iso_2,
            label: country.display_name,
          }))
        })
        .flat() || []
    )
  }, [regions])

  const billingAddress = customer.addresses?.find(
    (addr) => addr.is_default_billing
  )

  const [successState, setSuccessState] = React.useState(false)
  const [countryCode, setCountryCode] = React.useState(
    billingAddress?.country_code?.toLowerCase() || ""
  )
  const [rajaongkirSubdistrictId, setRajaongkirSubdistrictId] = React.useState(
    String(
      (billingAddress as any)?.metadata?.rajaongkir_subdistrict_id || ""
    )
  )
  const [rajaongkirCity, setRajaongkirCity] = React.useState(
    billingAddress?.city || ""
  )
  const [rajaongkirProvince, setRajaongkirProvince] = React.useState(
    billingAddress?.province || ""
  )
  const [rajaongkirPostalCode, setRajaongkirPostalCode] = React.useState(
    billingAddress?.postal_code || ""
  )
  const subdistrictRef = useRef<HTMLInputElement>(null)

  const initialState: Record<string, any> = {
    isDefaultBilling: true,
    isDefaultShipping: false,
    error: false,
    success: false,
  }

  if (billingAddress) {
    initialState.addressId = billingAddress.id
  }

  const [state, formAction] = useActionState(
    billingAddress ? updateCustomerAddress : addCustomerAddress,
    initialState
  )

  const clearState = () => {
    setSuccessState(false)
  }

  useEffect(() => {
    setSuccessState(state.success)
  }, [state])

  const currentInfo = useMemo(() => {
    if (!billingAddress) {
      return "No billing address"
    }

    const country =
      regionOptions?.find(
        (country) => country?.value === billingAddress.country_code
      )?.label || billingAddress.country_code?.toUpperCase()

    return (
      <div className="flex flex-col font-semibold" data-testid="current-info">
        <span>
          {billingAddress.first_name} {billingAddress.last_name}
        </span>
        <span>
          {billingAddress.address_1}
          {billingAddress.address_2 ? `, ${billingAddress.address_2}` : ""}
        </span>
        <span>
          {billingAddress.postal_code}, {billingAddress.city}
        </span>
        <span>{country}</span>
      </div>
    )
  }, [billingAddress, regionOptions])

  return (
    <form action={formAction} onReset={() => clearState()} className="w-full">
      <input type="hidden" name="addressId" value={billingAddress?.id} />
      <AccountInfo
        label="Billing address"
        currentInfo={currentInfo}
        isSuccess={successState}
        isError={!!state.error}
        clearState={clearState}
        data-testid="account-billing-address-editor"
      >
        <div className="grid grid-cols-1 gap-y-2">
          <div className="grid grid-cols-2 gap-x-2">
            <Input
              label="First name"
              name="first_name"
              defaultValue={billingAddress?.first_name || undefined}
              required
              data-testid="billing-first-name-input"
            />
            <Input
              label="Last name"
              name="last_name"
              defaultValue={billingAddress?.last_name || undefined}
              required
              data-testid="billing-last-name-input"
            />
          </div>
          <Input
            label="Phone"
            name="phone"
            type="phone"
            autoComplete="phone"
            required
            defaultValue={billingAddress?.phone ?? customer?.phone ?? ""}
            data-testid="billing-phone-input"
          />
          <Input
            label="Address"
            name="address_1"
            defaultValue={billingAddress?.address_1 || undefined}
            required
            data-testid="billing-address-1-input"
          />
          <Input
            label="Apartment, suite, etc."
            name="address_2"
            defaultValue={billingAddress?.address_2 || undefined}
            data-testid="billing-address-2-input"
          />
          <div className="grid grid-cols-[144px_1fr] gap-x-2">
            <Input
              label="Postal code"
              name="postal_code"
              defaultValue={billingAddress?.postal_code || undefined}
              required
              data-testid="billing-postcal-code-input"
            />
            {countryCode !== "id" && (
              <Input
                label="City"
                name="city"
                defaultValue={billingAddress?.city || undefined}
                required
                data-testid="billing-city-input"
              />
            )}
          </div>
          {countryCode !== "id" && (
            <Input
              label="Province"
              name="province"
              defaultValue={billingAddress?.province || undefined}
              data-testid="billing-province-input"
            />
          )}
          <NativeSelect
            name="country_code"
            defaultValue={billingAddress?.country_code || undefined}
            required
            data-testid="billing-country-code-select"
            value={countryCode}
            onChange={(e: React.ChangeEvent<HTMLSelectElement>) => {
              setCountryCode(e.target.value)
              setRajaongkirSubdistrictId("")
              setRajaongkirCity("")
              setRajaongkirProvince("")
              setRajaongkirPostalCode("")
            }}
          >
            <option value="">-</option>
            {regionOptions.map((option, i) => {
              return (
                <option key={i} value={option?.value}>
                  {option?.label}
                </option>
              )
            })}
          </NativeSelect>
          {countryCode === "id" && (
            <div className="col-span-2">
              <RajaOngkirAddressSelector
                onSelect={(data) => {
                  setRajaongkirSubdistrictId(String(data.subdistrict_id))
                  setRajaongkirCity(data.city)
                  setRajaongkirProvince(data.province)
                  setRajaongkirPostalCode(data.postal_code)
                }}
                selectedProvince={billingAddress?.province || undefined}
                selectedCity={billingAddress?.city || undefined}
              />
              <input
                type="hidden"
                name="rajaongkir_subdistrict_id"
                ref={subdistrictRef}
                value={rajaongkirSubdistrictId}
              />
              <input type="hidden" name="city" value={rajaongkirCity} />
              <input type="hidden" name="province" value={rajaongkirProvince} />
              <input type="hidden" name="postal_code" value={rajaongkirPostalCode} />
            </div>
          )}
        </div>
      </AccountInfo>
    </form>
  )
}

export default ProfileBillingAddress
