import { useCallback, useEffect, useState } from 'react'
import { MapPin, Pencil, Plus, Trash2 } from 'lucide-react'
import { Breadcrumbs, useToast } from '@meshkee/dashboard-ui'
import { AddressFormModal } from '../components/AddressFormModal'
import { Tooltip } from '../components/Tooltip'
import { useT } from '../i18n/useT'
import { ApiError, isAbortError } from '../lib/api'
import {
  listAddresses,
  removeAddress,
  type UserAddress,
} from '../services/addressService'
import pageStyles from '../components/PageContent.module.css'
import rowBtnStyles from '../components/VariationsModal.module.css'
import styles from './AddressesPage.module.css'

export function AddressesPage() {
  const { showToast } = useToast()
  const t = useT()
  const [addresses, setAddresses] = useState<UserAddress[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState('')
  const [removingId, setRemovingId] = useState<string | null>(null)
  const [modalOpen, setModalOpen] = useState(false)
  const [editingAddress, setEditingAddress] = useState<UserAddress | null>(null)

  const loadAddresses = useCallback(
    async (signal?: AbortSignal) => {
      setLoading(true)
      setError('')
      try {
        const data = await listAddresses(signal)
        if (signal?.aborted) return
        setAddresses(data.items)
      } catch (err) {
        if (isAbortError(err) || signal?.aborted) return
        setError(err instanceof ApiError ? err.message : t('addresses.error.load'))
      } finally {
        if (!signal?.aborted) setLoading(false)
      }
    },
    [t],
  )

  useEffect(() => {
    const controller = new AbortController()
    void loadAddresses(controller.signal)
    return () => controller.abort()
  }, [loadAddresses])

  function openCreateModal() {
    setEditingAddress(null)
    setModalOpen(true)
  }

  function openEditModal(item: UserAddress) {
    setEditingAddress(item)
    setModalOpen(true)
  }

  function handleSaved(saved: UserAddress) {
    setAddresses((prev) => {
      const index = prev.findIndex((item) => item.id === saved.id)
      if (index >= 0) {
        const next = [...prev]
        next[index] = saved
        return next
      }
      return [saved, ...prev]
    })
  }

  async function handleRemove(item: UserAddress) {
    setRemovingId(item.id)
    setError('')
    try {
      await removeAddress(item.id)
      setAddresses((prev) => prev.filter((row) => row.id !== item.id))
      showToast(t('addresses.toast.removed'), 'success')
    } catch (err) {
      const message = err instanceof ApiError ? err.message : t('addresses.error.remove')
      setError(message)
      showToast(message, 'error')
    } finally {
      setRemovingId(null)
    }
  }

  function formatRowLine(item: UserAddress) {
    return [
      item.label || null,
      item.province,
      item.city,
      item.address,
      item.postalCode,
      item.landline,
    ]
      .filter(Boolean)
      .join(' · ')
  }

  return (
    <main className={pageStyles.content}>
      <Breadcrumbs
        items={[{ label: t('nav.home'), href: '/' }, { label: t('addresses.title') }]}
      />

      <div className={pageStyles.pageHeader}>
        <div>
          <h2 className={pageStyles.pageTitle}>{t('addresses.title')}</h2>
          <p className={pageStyles.pageSubtitle}>{t('addresses.subtitle')}</p>
        </div>
      </div>

      {error && (
        <div className={styles.error} role="alert">
          {error}
        </div>
      )}

      <section className={styles.section}>
        <h3 className={styles.sectionTitle}>{t('addresses.editorTitle')}</h3>

        {loading && <p className={styles.status}>{t('addresses.loading')}</p>}

        {!loading && addresses.length === 0 && (
          <div className={styles.empty}>
            <MapPin size={28} />
            <p>{t('addresses.empty')}</p>
          </div>
        )}

        {!loading && addresses.length > 0 && (
          <ul className={styles.list}>
            {addresses.map((item) => (
              <li key={item.id} className={styles.row}>
                <div className={styles.rowLine} title={formatRowLine(item)}>
                  {item.label && <span className={styles.rowLabel}>{item.label}</span>}
                  <span className={styles.rowText}>
                    {[
                      item.province,
                      item.city,
                      item.address,
                      item.postalCode,
                      item.landline,
                    ]
                      .filter(Boolean)
                      .join(' · ')}
                  </span>
                </div>

                <div className={styles.rowActions}>
                  <Tooltip label={t('addresses.edit')}>
                    <button
                      type="button"
                      className={styles.editBtn}
                      onClick={() => openEditModal(item)}
                      aria-label={t('addresses.edit')}
                    >
                      <Pencil size={15} />
                    </button>
                  </Tooltip>
                  <Tooltip label={t('addresses.remove')}>
                    <button
                      type="button"
                      className={rowBtnStyles.removeRowBtn}
                      onClick={() => void handleRemove(item)}
                      disabled={removingId === item.id}
                      aria-label={t('addresses.remove')}
                    >
                      <Trash2 size={15} />
                    </button>
                  </Tooltip>
                </div>
              </li>
            ))}
          </ul>
        )}
      </section>

      <button
        type="button"
        className={styles.addFab}
        onClick={openCreateModal}
        aria-label={t('addresses.add')}
      >
        <Plus size={26} strokeWidth={2.5} />
      </button>

      <AddressFormModal
        open={modalOpen}
        address={editingAddress}
        onClose={() => {
          setModalOpen(false)
          setEditingAddress(null)
        }}
        onSaved={handleSaved}
      />
    </main>
  )
}
