import 'package:flutter/material.dart';
import 'package:superport/screens/common/custom_widgets.dart';
import 'package:superport/screens/common/theme_shadcn.dart';
import 'package:superport/utils/address_constants.dart';
import 'package:superport/models/address_model.dart';

/// 주소 입력 컴포넌트
///
/// 우편번호, 시/도 드롭다운, 상세주소로 구성된 주소 입력 폼입니다.
/// 1행 3열 구조로 배치되어 있으며, 각 필드는 SRP 원칙에 따라 개별적으로 관리됩니다.
class AddressInput extends StatefulWidget {
  /// 최초 우편번호 값
  final String initialZipCode;

  /// 최초 시/도 값
  final String initialRegion;

  /// 최초 상세 주소 값
  final String initialDetailAddress;

  /// 주소가 변경될 때 호출되는 콜백 함수
  /// zipCode, region, detailAddress를 매개변수로 전달합니다.
  final Function(String zipCode, String region, String detailAddress)
  onAddressChanged;

  /// 필수 입력 여부
  final bool isRequired;

  const AddressInput({
    super.key,
    this.initialZipCode = '',
    this.initialRegion = '',
    this.initialDetailAddress = '',
    required this.onAddressChanged,
    this.isRequired = false,
  });

  @override
  State<AddressInput> createState() => _AddressInputState();

  /// Address 객체를 받아 읽기 전용으로 표시하는 위젯
  static Widget readonly({required Address address}) {
    // 회사 리스트와 동일하게 address.toString() 사용, 스타일도 bodyStyle로 통일
    return Text(address.toString(), style: ShadcnTheme.bodyMedium);
  }
}

class _AddressInputState extends State<AddressInput> {
  // 텍스트 컨트롤러
  late TextEditingController _zipCodeController;
  late TextEditingController _detailAddressController;

  // 드롭다운 관련 변수
  String _selectedRegion = '';
  bool _showRegionDropdown = false;

  // 레이어 링크 (드롭다운 위치 조정용)
  final LayerLink _regionLayerLink = LayerLink();

  // 오버레이 엔트리 (드롭다운 메뉴)
  OverlayEntry? _regionOverlayEntry;

  // 포커스 노드
  final FocusNode _regionFocusNode = FocusNode();

  @override
  void initState() {
    super.initState();
    _zipCodeController = TextEditingController(text: widget.initialZipCode);
    _selectedRegion = widget.initialRegion;
    _detailAddressController = TextEditingController(
      text: widget.initialDetailAddress,
    );

    // 컨트롤러 변경 리스너 등록
    _zipCodeController.addListener(_notifyAddressChanged);
    _detailAddressController.addListener(_notifyAddressChanged);
  }

  @override
  void dispose() {
    _zipCodeController.dispose();
    _detailAddressController.dispose();
    _removeRegionOverlay();
    _regionFocusNode.dispose();
    super.dispose();
  }

  /// 주소 변경을 상위 위젯에 알립니다.
  void _notifyAddressChanged() {
    widget.onAddressChanged(
      _zipCodeController.text,
      _selectedRegion,
      _detailAddressController.text,
    );
  }

  /// 시/도 드롭다운을 토글합니다.
  void _toggleRegionDropdown() {
    setState(() {
      if (_showRegionDropdown) {
        _removeRegionOverlay();
      } else {
        _showRegionDropdown = true;
        _showRegionOverlay();
      }
    });
  }

  /// 시/도 드롭다운 오버레이를 제거합니다.
  void _removeRegionOverlay() {
    _regionOverlayEntry?.remove();
    _regionOverlayEntry = null;
    _showRegionDropdown = false;
  }

  /// 시/도 드롭다운 오버레이를 표시합니다.
  void _showRegionOverlay() {
    final RenderBox renderBox = context.findRenderObject() as RenderBox;
    final offset = renderBox.localToGlobal(Offset.zero);

    final availableHeight =
        MediaQuery.of(context).size.height - offset.dy - 100;
    final maxHeight = 300.0 < availableHeight ? 300.0 : availableHeight;

    _regionOverlayEntry = OverlayEntry(
      builder:
          (context) => Positioned(
            width: 200,
            child: CompositedTransformFollower(
              link: _regionLayerLink,
              showWhenUnlinked: false,
              offset: const Offset(0, 45),
              child: Material(
                elevation: 0,
                borderRadius: BorderRadius.circular(4),
                child: Container(
                  decoration: BoxDecoration(
                    color: ShadcnTheme.card,
                    border: Border.all(color: ShadcnTheme.border),
                    borderRadius: BorderRadius.circular(4),
                    boxShadow: ShadcnTheme.shadowSm,
                  ),
                  constraints: BoxConstraints(maxHeight: maxHeight),
                  child: SingleChildScrollView(
                    child: Column(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        ...KoreanRegions.topLevel.map(
                          (region) => InkWell(
                            onTap: () {
                              setState(() {
                                _selectedRegion = region;
                                _removeRegionOverlay();
                                _notifyAddressChanged();
                              });
                            },
                            child: Container(
                              padding: const EdgeInsets.symmetric(
                                horizontal: 16,
                                vertical: 12,
                              ),
                              width: double.infinity,
                              height: 48,
                              child: Text(
                                region,
                                style: ShadcnTheme.bodyMedium.copyWith(
                                  fontSize: 16,
                                ),
                              ),
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              ),
            ),
          ),
    );

    Overlay.of(context).insert(_regionOverlayEntry!);
  }

  @override
  Widget build(BuildContext context) {
    return FormFieldWrapper(
      label: '주소',
      isRequired: widget.isRequired,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // 우편번호 입력 필드 (1열)
              Expanded(
                flex: 2,
                child: TextField(
                  controller: _zipCodeController,
                  decoration: InputDecoration(
                    hintText: AddressLabels.zipCodeHint,
                    labelText: AddressLabels.zipCode,
                    border: const OutlineInputBorder(),
                  ),
                ),
              ),
              const SizedBox(width: 8),

              // 시/도 선택 드롭다운 (2열)
              Expanded(
                flex: 3,
                child: CompositedTransformTarget(
                  link: _regionLayerLink,
                  child: InkWell(
                    onTap: _toggleRegionDropdown,
                    child: Container(
                      padding: const EdgeInsets.symmetric(
                        horizontal: 12,
                        vertical: 0,
                      ),
                      height: 48,
                      decoration: BoxDecoration(
                        border: Border.all(color: Colors.grey.shade400),
                        borderRadius: BorderRadius.circular(4),
                      ),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          Text(
                            _selectedRegion.isEmpty
                                ? AddressLabels.regionHint
                                : _selectedRegion,
                            style: TextStyle(
                              fontSize: 16,
                              color:
                                  _selectedRegion.isEmpty
                                      ? Colors.grey.shade600
                                      : ShadcnTheme.foreground,
                            ),
                          ),
                          const Icon(Icons.arrow_drop_down),
                        ],
                      ),
                    ),
                  ),
                ),
              ),
              const SizedBox(width: 8),

              // 상세 주소 입력 필드 (3열)
              Expanded(
                flex: 7,
                child: TextField(
                  controller: _detailAddressController,
                  decoration: InputDecoration(
                    hintText: AddressLabels.detailHint,
                    labelText: AddressLabels.detail,
                    border: const OutlineInputBorder(),
                  ),
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}
