import AddressCard from './AddressCard'
import { LoadingDots, ButtonAria, Icon } from '$core-components'
import './AddressItem.scss'
import { useState, useEffect } from 'react'
import AddressDeleteWarning from './AddressDeleteWarning'
import AddressImport from './AddressImport'
import AddressForm from './AddressForm'
import { UStoreProvider } from '@ustore/core'
import { getAddressTypeLabel } from './addressUtils'
import { t } from '$themelocalization'
import { useMobile } from '$themehooks'


const downloadFile = (blob, filename) => {
	if (!blob) {
		console.error('Blob is empty or undefined')
		return
	}

	try {
		const url = URL.createObjectURL(blob)
		const link = document.createElement('a')
		link.href = url
		link.download = filename
		link.style.display = 'none'

		document.body.appendChild(link)
		link.click()
		document.body.removeChild(link)

		setTimeout(() => {
			URL.revokeObjectURL(url)
		}, 100)
	} catch (error) {
		console.error('Error downloading file:', error)
	}
}

const AddressItem = ({
	type,
	addressesList,
	onAddressDeleted,
	onAllAddressDeleted,
	onAddressAdded,
	getAddress,
	search = '',
	isLoading = false,
	...restProps
}) => {
	const title = `${getAddressTypeLabel(type)} ${t('AddressItem.Title.Addresses')}`
	const [showModal, setShowModal] = useState(false)
	const [showImportModal, setShowImportModal] = useState(false)
	const [showAddressFormModal, setShowAddressFormModal] = useState(false)
	const [fields, setFields] = useState([])
	const [showAll, setShowAll] = useState(false)
	const [countries, setCountries] = useState([])
	const [states, setStates] = useState({})
	const isMobile = useMobile()
	const matchesSearch = (address) => {
		if (!search || search.trim() === '') {
			return true
		}

		const searchLower = search.toLowerCase()
		const fieldsToSearch = [
			address.Name,
			address.PersonName,
			address.Company,
			address.Address1,
			address.Address2,
			address.City,
			address.State?.Name,
			address.ZipCode,
			address.Country?.Name,
			address.Phone,
			address.Email,
			address.Fax,
			address.AddressReference,
			address.EORINumber,
			address.TaxID,
		]

		return fieldsToSearch.some(
			(field) => field && String(field).toLowerCase().includes(searchLower)
		)
	}

	const filteredAddresses = addressesList
		? addressesList.filter(matchesSearch)
		: []


	useEffect(() => {
		const fetchForm = async (type) => {
			const addresses = await UStoreProvider.api.addresses.getAddressFormFields(type)
			setFields(addresses?.Fields || [])
			const countriesFieldOptions =
				addresses?.Fields.find((field) => field.Name === 'CountryID')?.Options || []

			const countries = countriesFieldOptions.map((option) => ({
				Name: option.Name,
				ID: option.Value,
			}))

			const states = {}
			for (const country of countries) {
				states[country.ID] = await UStoreProvider.api.addresses.getStates(
					country.ID
				)
			}

			setCountries(countries)
			setStates(states)
		}

		fetchForm(type)
	}, [type])

	const maxVisibleDesktop = 4
	const maxVisibleMobile = 2
	const maxVisible = isMobile ? maxVisibleMobile : maxVisibleDesktop
	const shouldShowExpander =
		filteredAddresses && filteredAddresses.length > maxVisible
	const visibleAddresses =
		showAll || !shouldShowExpander
			? filteredAddresses || []
			: (filteredAddresses || []).slice(0, maxVisible)

	const toggleExpander = () => {
		setShowAll(true)
	}

	const handleExportClick = async (type) => {
		const hasSearchFilter = Boolean(search && search.trim())
		const filteredIds = hasSearchFilter
			? (filteredAddresses || [])
				.map((address) => address?.ID)
				.filter((id) => typeof id !== 'undefined' && id !== null)
			: null

		try {
			const response = await UStoreProvider.api.addresses.exportAddresses({
				type,
				IDs: filteredIds && filteredIds.length > 0 ? filteredIds : null,
			})

			if (response instanceof Blob) {
				const date = new Date().toISOString().split('T')[0]
				const time = new Date().toTimeString().slice(0, 5).replace(':', '-')
				const dateTime = `${date}_${time}`
				const filename =
					type === 2
						? `BillingAddresses_${dateTime}.xlsx`
						: `ShippingAddresses_${dateTime}.xlsx`
				downloadFile(response, filename)
			} else {
				console.error('API response is not a blob:', response)
			}
		} catch (error) {
			console.error('Error exporting addresses:', error)
		}
	}

	const handleAddressAdded = async (values) => {
		const payload = {
			...values,
			Type: type,
		}
		try {
			const response = await UStoreProvider.api.addresses.addAddress(
				payload
			)
			const newAddressId = response?.ID
			const allAddresses = await UStoreProvider.api.addresses.getAddresses()
			const newAddress = allAddresses.find((addr) => addr.ID === newAddressId)
			onAddressAdded(newAddressId, newAddress || payload)
		} catch (error) {
			if (error.TypeName === 'ValidationError.AlreadyExists') {
				throw error
			}
			UStoreProvider.contextService.getValue('onGeneralError')(error)
		}
	}

	return (
		<>
			<div className={`address-item address-item-${type}`} {...restProps}>
				<div className='address-item-header'>
					<h3 className='address-item-title'>{title}</h3>
					<div className='address-item-export-import'>
						<ButtonAria
							className='button button-transparent address-item-import-button'
							onClick={() => {
								setShowImportModal(true)
							}}
							noTruncate={true}
						>
							<Icon
								name='upload.svg'
								width='16px'
								height='16px'
								title={t('AddressItem.Button.Import')}
							/>
						</ButtonAria>
						<ButtonAria
							className='button button-transparent address-item-export-button'
							onClick={() => handleExportClick(type)}
							noTruncate={true}
							disabled={search && filteredAddresses.length === 0}
						>
							<Icon
								name='download.svg'
								width='16px'
								height='16px'
								title={t('AddressItem.Button.Export')}
							/>
						</ButtonAria>
					</div>

					<ButtonAria
						className='button button-transparent address-item-delete-button'
						onClick={() => {
							setShowModal(true)
						}}
						noTruncate={true}
						disabled={filteredAddresses.length === 0}
					>
						<Icon
							name='cart_delete.svg'
							width='20px'
							height='20px'
							title={t('AddressItem.Button.DeleteAll',{ type: title?.toLowerCase() })}
						/>
					</ButtonAria>
					<ButtonAria
						className='button button-secondary address-item-new-button'
						onClick={() => {
							setShowAddressFormModal(true)
						}}
						text={t('AddressItem.Button.New')}
						noTruncate={true}
					></ButtonAria>
				</div>
				<div className={filteredAddresses.length === 0 ? 'address-item-body-empty address-item-body' : 'address-item-body'}>
					{isLoading && <LoadingDots className="loading-dots address-item-loading" />}
					{!isLoading && filteredAddresses && filteredAddresses.length === 0 ? (
						<p className='address-item-empty'>
							{search && search.trim() !== '' ? (
								t('AddressItem.Empty.NoResults', { search })
							) : (
								<>
									{t('AddressItem.Empty.NoAddresses')} <br /> {t('AddressItem.Empty.PleaseCreate')}
								</>
							)}
						</p>
					) : (
						<>
							{visibleAddresses.map((address, index) => (
								<AddressCard
									key={index}
									address={address}
									onAddressDeleted={onAddressDeleted}
									onAddressAdded={onAddressAdded}
									formFields={fields}
									countries={countries}
									states={states}
								/>
							))}
							{shouldShowExpander && !showAll && (
								<div className='address-item-expander-container'>
									<button
										className='address-item-expander'
										onClick={toggleExpander}
									>
										{t('AddressItem.Button.ViewAll')}
										<Icon
											name={'cart_view_more.svg'}
											width='10px'
											height='10px'
										/>
									</button>
								</div>
							)}
						</>
					)}
				</div>
			</div>
			<AddressDeleteWarning
				showModal={showModal}
				setShowModal={setShowModal}
				onAddressDeleted={onAllAddressDeleted}
				type={type}
			/>
			<AddressImport
				showModal={showImportModal}
				setShowModal={setShowImportModal}
				type={type}
				onAddressAdded={getAddress}
			/>
			<AddressForm
				showModal={showAddressFormModal}
				setShowModal={setShowAddressFormModal}
				type={type}
				countries={countries}
				states={states}
				formFields={fields}
				onSubmit={handleAddressAdded}
			/>
		</>
	)
}

export default AddressItem
