import 'package:flutter/material.dart';
import 'package:shadcn_ui/shadcn_ui.dart';

class SuperportShadSelect<T> extends StatefulWidget {
  final String label;
  final String? placeholder;
  final List<T> items;
  final T? value;
  final String Function(T) itemLabel;
  final ValueChanged<T?>? onChanged;
  final bool enabled;
  final bool searchable;
  final String? errorText;
  final String? helperText;
  final Widget? prefixIcon;
  final VoidCallback? onClear;
  final Future<List<T>> Function(String)? onSearch;
  final bool required;
  
  const SuperportShadSelect({
    super.key,
    required this.label,
    required this.items,
    required this.itemLabel,
    this.placeholder,
    this.value,
    this.onChanged,
    this.enabled = true,
    this.searchable = false,
    this.errorText,
    this.helperText,
    this.prefixIcon,
    this.onClear,
    this.onSearch,
    this.required = false,
  });
  
  @override
  State<SuperportShadSelect<T>> createState() => _SuperportShadSelectState<T>();
}

class _SuperportShadSelectState<T> extends State<SuperportShadSelect<T>> {
  final TextEditingController _searchController = TextEditingController();
  List<T> _filteredItems = [];
  bool _isSearching = false;
  
  @override
  void initState() {
    super.initState();
    _filteredItems = widget.items;
  }
  
  @override
  void didUpdateWidget(SuperportShadSelect<T> oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.items != widget.items) {
      _filteredItems = widget.items;
    }
  }
  
  @override
  void dispose() {
    _searchController.dispose();
    super.dispose();
  }
  
  void _handleSearch(String query) async {
    if (query.isEmpty) {
      setState(() {
        _filteredItems = widget.items;
        _isSearching = false;
      });
      return;
    }
    
    setState(() {
      _isSearching = true;
    });
    
    if (widget.onSearch != null) {
      final results = await widget.onSearch!(query);
      setState(() {
        _filteredItems = results;
        _isSearching = false;
      });
    } else {
      setState(() {
        _filteredItems = widget.items.where((item) {
          return widget.itemLabel(item)
              .toLowerCase()
              .contains(query.toLowerCase());
        }).toList();
        _isSearching = false;
      });
    }
  }
  
  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);
    
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Row(
          children: [
            Text(
              widget.label,
              style: theme.textTheme.small.copyWith(
                fontWeight: FontWeight.w600,
                fontSize: 14,
              ),
            ),
            if (widget.required)
              Text(
                ' *',
                style: theme.textTheme.small.copyWith(
                  color: theme.colorScheme.destructive,
                  fontWeight: FontWeight.w600,
                ),
              ),
          ],
        ),
        const SizedBox(height: 8),
        ShadSelect<T>(
          placeholder: widget.placeholder != null 
              ? Text(widget.placeholder!)
              : const Text('선택하세요'),
          selectedOptionBuilder: (context, value) {
            if (value == null) return const Text('선택하세요');
            return Text(widget.itemLabel(value));
          },
          enabled: widget.enabled,
          options: _filteredItems.map((item) {
            return ShadOption(
              value: item,
              child: Row(
                children: [
                  if (widget.value == item)
                    const Padding(
                      padding: EdgeInsets.only(right: 8),
                      child: Icon(
                        Icons.check,
                        size: 16,
                      ),
                    ),
                  Expanded(
                    child: Text(
                      widget.itemLabel(item),
                      style: theme.textTheme.small.copyWith(
                        fontWeight: widget.value == item 
                            ? FontWeight.w600 
                            : FontWeight.w400,
                      ),
                    ),
                  ),
                ],
              ),
            );
          }).toList(),
          onChanged: widget.onChanged,
        ),
        if (widget.errorText != null) ...[
          const SizedBox(height: 4),
          Text(
            widget.errorText!,
            style: theme.textTheme.small.copyWith(
              color: theme.colorScheme.destructive,
              fontSize: 12,
            ),
          ),
        ],
        if (widget.helperText != null && widget.errorText == null) ...[
          const SizedBox(height: 4),
          Text(
            widget.helperText!,
            style: theme.textTheme.small.copyWith(
              color: theme.colorScheme.mutedForeground,
              fontSize: 12,
            ),
          ),
        ],
      ],
    );
  }
}

class CascadeSelect<T, U> extends StatefulWidget {
  final String parentLabel;
  final String childLabel;
  final List<T> parentItems;
  final String Function(T) parentItemLabel;
  final Future<List<U>> Function(T) getChildItems;
  final String Function(U) childItemLabel;
  final T? parentValue;
  final U? childValue;
  final ValueChanged<T?>? onParentChanged;
  final ValueChanged<U?>? onChildChanged;
  final bool enabled;
  final bool searchable;
  final bool required;
  
  const CascadeSelect({
    super.key,
    required this.parentLabel,
    required this.childLabel,
    required this.parentItems,
    required this.parentItemLabel,
    required this.getChildItems,
    required this.childItemLabel,
    this.parentValue,
    this.childValue,
    this.onParentChanged,
    this.onChildChanged,
    this.enabled = true,
    this.searchable = true,
    this.required = false,
  });
  
  @override
  State<CascadeSelect<T, U>> createState() => _CascadeSelectState<T, U>();
}

class _CascadeSelectState<T, U> extends State<CascadeSelect<T, U>> {
  List<U> _childItems = [];
  bool _isLoadingChildren = false;
  
  @override
  void initState() {
    super.initState();
    if (widget.parentValue != null) {
      _loadChildItems(widget.parentValue as T);
    }
  }
  
  @override
  void didUpdateWidget(CascadeSelect<T, U> oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.parentValue != widget.parentValue && 
        widget.parentValue != null) {
      _loadChildItems(widget.parentValue as T);
    }
  }
  
  Future<void> _loadChildItems(T parentValue) async {
    setState(() {
      _isLoadingChildren = true;
    });
    
    try {
      final items = await widget.getChildItems(parentValue);
      if (mounted) {
        setState(() {
          _childItems = items;
          _isLoadingChildren = false;
        });
      }
    } catch (e) {
      if (mounted) {
        setState(() {
          _childItems = [];
          _isLoadingChildren = false;
        });
      }
    }
  }
  
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        SuperportShadSelect<T>(
          label: widget.parentLabel,
          items: widget.parentItems,
          itemLabel: widget.parentItemLabel,
          value: widget.parentValue,
          onChanged: (value) {
            widget.onParentChanged?.call(value);
            widget.onChildChanged?.call(null);
            if (value != null) {
              _loadChildItems(value);
            } else {
              setState(() {
                _childItems = [];
              });
            }
          },
          enabled: widget.enabled,
          searchable: widget.searchable,
          required: widget.required,
          placeholder: '${widget.parentLabel}을(를) 선택하세요',
        ),
        const SizedBox(height: 16),
        SuperportShadSelect<U>(
          label: widget.childLabel,
          items: _childItems,
          itemLabel: widget.childItemLabel,
          value: widget.childValue,
          onChanged: widget.onChildChanged,
          enabled: widget.enabled && 
                  widget.parentValue != null && 
                  !_isLoadingChildren,
          searchable: widget.searchable,
          required: widget.required,
          placeholder: _isLoadingChildren 
              ? '로딩 중...' 
              : widget.parentValue == null
                  ? '먼저 ${widget.parentLabel}을(를) 선택하세요'
                  : '${widget.childLabel}을(를) 선택하세요',
        ),
      ],
    );
  }
}