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

import '../application/adjust_inventory_quantity.dart';
import '../application/create_inventory_item.dart';
import '../application/get_inventory_items.dart';
import '../application/inventory_controller.dart';
import '../application/update_inventory_item.dart';
import '../domain/inventory_item.dart';
import '../domain/inventory_repository.dart';
import 'inventory_action_snack_bar.dart';
import 'widgets/adjust_quantity_dialog.dart';
import 'widgets/inventory_detail_panel.dart';
import 'widgets/inventory_item_card.dart';

/// The main inventory workspace page.
///
/// Provides a search bar, status filter chips, a scrollable item list, and a
/// detail panel that appears when an item is selected. Quantity adjustments are
/// performed via a modal dialog and confirmed with a SnackBar.
class InventoryPage extends StatefulWidget {
  final InventoryRepository repository;

  /// Optional callback to navigate to the Products page for a given SKU.
  /// Provided by the app layer to enable cross-feature handoffs.
  final void Function(String sku)? onViewProduct;

  /// Optional initial status filter to apply on first load (e.g. `'lowStock'`).
  final String? initialFilter;

  /// Optional initial search query to apply on first load.
  final String? initialQuery;

  /// Optional SKU to pre-select on first load (from a navigation handoff).
  final String? initialSelectedSku;

  const InventoryPage({
    super.key,
    required this.repository,
    this.onViewProduct,
    this.initialFilter,
    this.initialQuery,
    this.initialSelectedSku,
  });

  @override
  State<InventoryPage> createState() => _InventoryPageState();
}

class _InventoryPageState extends State<InventoryPage> {
  late final InventoryController _controller;
  late final TextEditingController _searchController;

  @override
  void initState() {
    super.initState();
    _controller = InventoryController(
      GetInventoryItems(widget.repository),
      AdjustInventoryQuantity(widget.repository),
      CreateInventoryItem(widget.repository),
      UpdateInventoryItem(widget.repository),
    );
    _searchController = TextEditingController(text: widget.initialQuery ?? '');

    // Apply any initial filter / query before loading.
    if (widget.initialFilter != null) {
      _controller.activeFilter = widget.initialFilter;
    }
    if (widget.initialQuery != null && widget.initialQuery!.isNotEmpty) {
      _controller.searchQuery = widget.initialQuery!;
    }

    _controller.addListener(_onControllerChanged);

    _controller.load().then((_) {
      if (widget.initialSelectedSku != null) {
        _controller.selectBySku(widget.initialSelectedSku!);
      }
    });
  }

  @override
  void dispose() {
    _controller.removeListener(_onControllerChanged);
    _controller.dispose();
    _searchController.dispose();
    super.dispose();
  }

  void _onControllerChanged() {
    final result = _controller.lastActionResult;
    if (result != null && !_controller.isUpdating) {
      showInventoryActionSnackBar(
        context,
        result,
        successMessage: result.success ? 'Quantity updated.' : 'Update failed.',
      );
      // Consume the result so it is not shown again on the next rebuild.
      _controller.lastActionResult = null;
    }
  }

  Future<void> _handleAdjustQuantity(InventoryItem item) async {
    final dialogResult = await showAdjustQuantityDialog(context, item);
    if (dialogResult == null) return;
    await _controller.adjustQuantity(item.id, dialogResult.delta, dialogResult.reason);
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _controller,
      builder: (context, _) {
        if (_controller.isLoading) {
          return const KcLoadingState(message: 'Loading inventory…');
        }

        if (_controller.error != null) {
          return KcErrorState(message: 'Failed to load inventory data.', onRetry: _controller.load);
        }

        return LayoutBuilder(
          builder: (context, constraints) {
            final isWide = constraints.maxWidth >= KcBreakpoints.medium;

            return Column(
              children: [
                _InventoryToolbar(
                  searchController: _searchController,
                  activeFilter: _controller.activeFilter,
                  itemCount: _controller.items.length,
                  onSearchChanged: (q) {
                    _controller.setSearchQuery(q);
                  },
                  onFilterChanged: _controller.setFilter,
                ),
                Expanded(
                  child: isWide
                      ? _WideLayout(
                          controller: _controller,
                          onAdjustQuantity: _handleAdjustQuantity,
                          onViewProduct: widget.onViewProduct,
                        )
                      : _NarrowLayout(
                          controller: _controller,
                          onAdjustQuantity: _handleAdjustQuantity,
                          onViewProduct: widget.onViewProduct,
                        ),
                ),
              ],
            );
          },
        );
      },
    );
  }
}

// ── Toolbar ────────────────────────────────────────────────────────────────────

class _InventoryToolbar extends StatelessWidget {
  final TextEditingController searchController;
  final String? activeFilter;
  final int itemCount;
  final ValueChanged<String> onSearchChanged;
  final ValueChanged<String?> onFilterChanged;

  const _InventoryToolbar({
    required this.searchController,
    required this.activeFilter,
    required this.itemCount,
    required this.onSearchChanged,
    required this.onFilterChanged,
  });

  static const _filters = [
    (label: 'All', value: null),
    (label: 'In Stock', value: 'inStock'),
    (label: 'Low Stock', value: 'lowStock'),
    (label: 'Out of Stock', value: 'outOfStock'),
    (label: 'Draft', value: 'draft'),
  ];

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.fromLTRB(KcSpacing.md, KcSpacing.md, KcSpacing.md, 0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // Search bar
          TextField(
            controller: searchController,
            onChanged: onSearchChanged,
            decoration: InputDecoration(
              hintText: 'Search by name or SKU…',
              prefixIcon: const Icon(Icons.search),
              suffixIcon: searchController.text.isNotEmpty
                  ? IconButton(
                      icon: const Icon(Icons.clear),
                      tooltip: 'Clear search',
                      onPressed: () {
                        searchController.clear();
                        onSearchChanged('');
                      },
                    )
                  : null,
              border: const OutlineInputBorder(),
              isDense: true,
            ),
          ),
          const SizedBox(height: KcSpacing.sm),

          // Filter chips + item count
          Row(
            children: [
              Expanded(
                child: SingleChildScrollView(
                  scrollDirection: Axis.horizontal,
                  child: Row(
                    children: _filters.map((f) {
                      final isSelected = activeFilter == f.value;
                      return Padding(
                        padding: const EdgeInsets.only(right: KcSpacing.xs),
                        child: FilterChip(
                          label: Text(f.label),
                          selected: isSelected,
                          onSelected: (_) => onFilterChanged(f.value),
                        ),
                      );
                    }).toList(),
                  ),
                ),
              ),
              const SizedBox(width: KcSpacing.sm),
              Text(
                '$itemCount item${itemCount == 1 ? '' : 's'}',
                style: Theme.of(context).textTheme.bodySmall?.copyWith(color: KcColors.neutral),
              ),
            ],
          ),
          const SizedBox(height: KcSpacing.sm),
        ],
      ),
    );
  }
}

// ── Wide layout (master + detail side-by-side) ─────────────────────────────────

class _WideLayout extends StatelessWidget {
  final InventoryController controller;
  final Future<void> Function(InventoryItem) onAdjustQuantity;
  final void Function(String sku)? onViewProduct;

  const _WideLayout({
    required this.controller,
    required this.onAdjustQuantity,
    required this.onViewProduct,
  });

  @override
  Widget build(BuildContext context) {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        // Master list — 40% width
        SizedBox(
          width: 340,
          child: _ItemList(controller: controller, onViewProduct: onViewProduct),
        ),
        const VerticalDivider(width: 1),
        // Detail panel — remaining width
        Expanded(
          child: controller.selectedItem == null
              ? const KcEmptyState(
                  icon: Icons.inventory_2_outlined,
                  message: 'Select an item from the list to view details.',
                )
              : InventoryDetailPanel(
                  item: controller.selectedItem!,
                  isUpdating: controller.isUpdating,
                  onAdjustQuantity: () => onAdjustQuantity(controller.selectedItem!),
                  onViewProduct: onViewProduct != null
                      ? () => onViewProduct!(controller.selectedItem!.sku)
                      : null,
                ),
        ),
      ],
    );
  }
}

// ── Narrow layout (list only; tap navigates to detail) ─────────────────────────

class _NarrowLayout extends StatelessWidget {
  final InventoryController controller;
  final Future<void> Function(InventoryItem) onAdjustQuantity;
  final void Function(String sku)? onViewProduct;

  const _NarrowLayout({
    required this.controller,
    required this.onAdjustQuantity,
    required this.onViewProduct,
  });

  @override
  Widget build(BuildContext context) {
    return _ItemList(
      controller: controller,
      onViewProduct: onViewProduct,
      onTap: (item) {
        Navigator.of(context).push(
          MaterialPageRoute<void>(
            builder: (_) => _InventoryDetailPage(
              item: item,
              controller: controller,
              onAdjustQuantity: onAdjustQuantity,
              onViewProduct: onViewProduct,
            ),
          ),
        );
      },
    );
  }
}

// ── Shared item list ───────────────────────────────────────────────────────────

class _ItemList extends StatelessWidget {
  final InventoryController controller;
  final void Function(String sku)? onViewProduct;

  /// Optional tap handler for narrow layout navigation.
  final void Function(InventoryItem)? onTap;

  const _ItemList({required this.controller, required this.onViewProduct, this.onTap});

  @override
  Widget build(BuildContext context) {
    if (controller.items.isEmpty) {
      return const KcEmptyState(
        icon: Icons.inventory_2_outlined,
        message: 'No items found. Try adjusting your search or filter.',
      );
    }

    return ListView.separated(
      padding: const EdgeInsets.all(KcSpacing.md),
      itemCount: controller.items.length,
      separatorBuilder: (_, _) => const SizedBox(height: KcSpacing.sm),
      itemBuilder: (context, index) {
        final item = controller.items[index];
        final isSelected = controller.selectedItem?.id == item.id;

        return GestureDetector(
          onTap: () {
            controller.selectItem(item);
            onTap?.call(item);
          },
          child: AnimatedContainer(
            duration: const Duration(milliseconds: 150),
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(8),
              border: Border.all(
                color: isSelected ? Theme.of(context).colorScheme.primary : Colors.transparent,
                width: 2,
              ),
            ),
            child: InventoryItemCard(
              item: item,
              onViewProduct: onViewProduct != null ? () => onViewProduct!(item.sku) : null,
            ),
          ),
        );
      },
    );
  }
}

// ── Narrow detail page (pushed on mobile) ─────────────────────────────────────

class _InventoryDetailPage extends StatelessWidget {
  final InventoryItem item;
  final InventoryController controller;
  final Future<void> Function(InventoryItem) onAdjustQuantity;
  final void Function(String sku)? onViewProduct;

  const _InventoryDetailPage({
    required this.item,
    required this.controller,
    required this.onAdjustQuantity,
    required this.onViewProduct,
  });

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(item.name)),
      body: AnimatedBuilder(
        animation: controller,
        builder: (context, _) {
          // Use the refreshed item from the controller if available.
          final current = controller.selectedItem?.id == item.id ? controller.selectedItem! : item;
          return InventoryDetailPanel(
            item: current,
            isUpdating: controller.isUpdating,
            onAdjustQuantity: () => onAdjustQuantity(current),
            onViewProduct: onViewProduct != null ? () => onViewProduct!(current.sku) : null,
          );
        },
      ),
    );
  }
}
