import React, { useState, useEffect, useRef } from 'react'
import './AddressCard.scss'
import { ButtonAria, Icon } from '$core-components'
import ConfirmationDialog from '../cart/ConfirmationDialog'
import { UStoreProvider } from '@ustore/core'
import AddressForm from './AddressForm'
import { useMobile } from '$themehooks'
import { t } from '$themelocalization'
import { buildAddressLines } from './addressUtils'

const TOOLTIP_DELAY = 2000

const AddressCard = ({ address, onAddressDeleted, onAddressAdded, formFields, countries, states }) => {
	if (!address) {
		return null
	}

	const isMobile = useMobile()
	const numOfVisibleRows = isMobile ? 5 : 6

	const {
		PersonName: personName,
		Company: company,
		City: city,
		State: stateObj = null,
		Country: countryObj = null,
	} = address

	const state = stateObj?.Name ?? ""
	const country = countryObj?.Name ?? ""
	const isCountrySupported = countryObj?.SupportedInStore ?? true
	const isStateSupported = stateObj?.SupportedInStore ?? true


	const [isTooltipVisible, setIsTooltipVisible] = useState(false)
	const [isTooltipHeaderVisible, setIsTooltipHeaderVisible] = useState(false)
	const [showConfirmationDialog, setShowConfirmationDialog] = useState(false)
	const [showEditModal, setShowEditModal] = useState(false)
	const tooltipTimeoutRef = useRef(null)
	const headerTooltipTimeoutRef = useRef(null)
	const headerTitleRef = useRef(null)

	const allLines = buildAddressLines(address)
	const visibleLines = allLines.slice(0, numOfVisibleRows)
	const hasMoreLines = allLines.length > numOfVisibleRows
	const fullAddressText = allLines.join('\n')

	const handleMouseEnter = () => {
		tooltipTimeoutRef.current = setTimeout(() => {
			setIsTooltipVisible(true)
		}, TOOLTIP_DELAY)
	}

	const handleMouseLeave = () => {
		if (tooltipTimeoutRef.current) {
			clearTimeout(tooltipTimeoutRef.current)
			tooltipTimeoutRef.current = null
		}
		setIsTooltipVisible(false)
	}

	useEffect(() => {
		return () => {
			if (tooltipTimeoutRef.current) {
				clearTimeout(tooltipTimeoutRef.current)
			}
		}
	}, [])

	const title = address.Name ? address.Name : `${personName} ${company} - ${country} ${state} ${city}`.trim()

	const handleHeaderMouseEnter = () => {
		headerTooltipTimeoutRef.current = setTimeout(() => {
			setIsTooltipHeaderVisible(true)
		}, TOOLTIP_DELAY)
	}

	const handleHeaderMouseLeave = () => {
		if (headerTooltipTimeoutRef.current) {
			clearTimeout(headerTooltipTimeoutRef.current)
			headerTooltipTimeoutRef.current = null
		}
		setIsTooltipHeaderVisible(false)
	}

	useEffect(() => {
		return () => {
			if (headerTooltipTimeoutRef.current) {
				clearTimeout(headerTooltipTimeoutRef.current)
			}
		}
	}, [])

	const handleDeleteItem = async () => {
		try {
			await UStoreProvider.api.addresses.clearAddress({
				Type: address.Type,
				IDs: [address.ID],
			})

			if (onAddressDeleted) {
				onAddressDeleted(address.ID)
			}

			setShowConfirmationDialog(false)
		} catch (error) {
			console.error('Error deleting address:', error)
		}
	}

	const updateAddress = async (values) => {
		const payload = {
			Type: address.Type,
			...values,
		}
		try {
			await UStoreProvider.api.addresses.updateAddress(
				address.ID,
				payload
			)
			const allAddresses = await UStoreProvider.api.addresses.getAddresses()
			const updatedAddress = allAddresses.find((addr) => addr.ID === address.ID)
			onAddressAdded(address.ID, updatedAddress || payload)
		} catch (error) {
			if (error.TypeName === 'ValidationError.AlreadyExists') {
				throw error
			}
			UStoreProvider.contextService.getValue('onGeneralError')(error)
		}
	}

	return (
		<>
			<div className='address-card'>
				<div
					className='address-header'
				>
					{isCountrySupported && isStateSupported ? null : (
						<div className='address-header-warning'>
							<Icon name={`cart_error.svg`} width="12px" height="12px" wrapperClassName={`error-icon address-header-error`} />
							<p className="address-header-error-text">
								{t('AddressCard.Warning.NotSupported', {
									type: !isCountrySupported ? t('AddressCard.Warning.Country') : t('AddressCard.Warning.State')
								})}
							</p>
						</div>
					)}

					<p className='address-header-title' ref={headerTitleRef}
						onMouseEnter={handleHeaderMouseEnter}
						onMouseLeave={handleHeaderMouseLeave}>{title}</p>
					{isTooltipHeaderVisible && title && (
						<div className='address-tooltip'>{title}</div>
					)}
					<ButtonAria
						className='button button-transparent address-card-edit-button'
						onClick={() => {
							setShowEditModal(true)
						}}
						noTruncate={true}
					>
						<Icon
							name='cart_edit.svg'
							width='16px'
							height='16px'
							title={t('AddressCard.Button.Edit')}
						/>
					</ButtonAria>
					<ButtonAria
						className='button button-transparent address-card-delete-button'
						onClick={() => {
							setShowConfirmationDialog(true)
						}}
						noTruncate={true}
					>
						<Icon
							name='cart_delete.svg'
							width='16px'
							height='16px'
							title={t('AddressCard.Button.Delete')}
						/>
					</ButtonAria>
				</div>
				<div
					className='address-body'
					onMouseEnter={handleMouseEnter}
					onMouseLeave={handleMouseLeave}
				>
					{visibleLines.map((line, index) => (
						<p key={index}>{line}</p>
					))}
					{hasMoreLines && <p className='address-ellipsis'>…</p>}
					{isTooltipVisible && fullAddressText && (
						<div className='address-tooltip'>{fullAddressText}</div>
					)}
				</div>
			</div>
			<ConfirmationDialog
				open={showConfirmationDialog}
				confirmationText={t('AddressCard.Confirmation.DeleteMessage')}
				confirmButtonText={t('AddressCard.Button.Delete')}
				rejectButtonText={t('AddressForm.Button.Cancel')}
				onReject={() => setShowConfirmationDialog(false)}
				onConfirm={() => {
					handleDeleteItem()
				}}
			/>
			<AddressForm
				showModal={showEditModal}
				setShowModal={setShowEditModal}
				type={address.Type}
				address={address}
				formFields={formFields}
				countries={countries}
				states={states}
				onSubmit={updateAddress}
			/>
		</>
	)
}

export default AddressCard
