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

import '../application/get_product_drafts.dart';
import '../application/product_publishing_controller.dart';
import '../application/publish_product.dart';
import '../application/update_product_category.dart';
import '../application/update_product_description.dart';
import '../application/update_product_name.dart';
import '../application/update_product_price.dart';
import '../application/update_product_status.dart';
import '../domain/product_publishing_repository.dart';
import '../domain/publish_status.dart';
import 'widgets/product_draft_card.dart';
import 'widgets/product_preview_panel.dart';
import 'widgets/status_action_snack_bar.dart';

/// The main Product Publishing Workspace page.
///
/// Displays a list of product drafts on the left and a preview panel on the
/// right. Users can select a draft to preview and publish it to the store.
class ProductPublishingPage extends StatefulWidget {
  final ProductPublishingRepository repository;

  /// Optional callback to navigate to the Policy page.
  /// Provided by the app layer to enable cross-feature handoffs.
  final VoidCallback? onViewPolicy;

  /// Optional initial status filter to apply on first load (e.g. `'draft'`).
  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 ProductPublishingPage({
    super.key,
    required this.repository,
    this.onViewPolicy,
    this.initialFilter,
    this.initialQuery,
    this.initialSelectedSku,
  });

  @override
  State<ProductPublishingPage> createState() => _ProductPublishingPageState();
}

class _ProductPublishingPageState extends State<ProductPublishingPage> {
  late final ProductPublishingController controller;
  late final FocusNode _listFocusNode;

  @override
  void initState() {
    super.initState();
    _listFocusNode = FocusNode();

    final repo = widget.repository;
    controller = ProductPublishingController(
      GetProductDrafts(repo),
      PublishProduct(repo),
      UpdateProductStatus(repo),
      UpdateProductPrice(repo),
      UpdateProductName(repo),
      UpdateProductDescription(repo),
      UpdateProductCategory(repo),
    );

    controller.addListener(_onControllerChanged);

    // 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.load().then((_) {
      // After data is loaded, try to pre-select by SKU if requested.
      if (widget.initialSelectedSku != null) {
        controller.selectBySku(widget.initialSelectedSku!);
      }
    });
  }

  @override
  void dispose() {
    controller.removeListener(_onControllerChanged);
    controller.dispose();
    _listFocusNode.dispose();
    super.dispose();
  }

  void _onControllerChanged() {
    final result = controller.lastActionResult;
    if (result != null) {
      controller.consumeActionResult();
      showStatusActionSnackBar(context, result);
    }

    final priceResult = controller.lastPriceResult;
    if (priceResult != null) {
      controller.consumePriceResult();
      showPriceActionSnackBar(context, priceResult);
    }

    final nameResult = controller.lastNameResult;
    if (nameResult != null) {
      controller.consumeNameResult();
      showNameActionSnackBar(context, nameResult);
    }

    final descriptionResult = controller.lastDescriptionResult;
    if (descriptionResult != null) {
      controller.consumeDescriptionResult();
      showDescriptionActionSnackBar(context, descriptionResult);
    }

    final categoryResult = controller.lastCategoryResult;
    if (categoryResult != null) {
      controller.consumeCategoryResult();
      showCategoryActionSnackBar(context, categoryResult);
    }

    final bulkResult = controller.lastBulkActionResult;
    if (bulkResult != null) {
      controller.consumeBulkActionResult();
      showBulkActionSnackBar(context, bulkResult);
    }
  }

  /// Shows a confirmation dialog before executing bulk move-to-draft.
  Future<void> _confirmBulkMoveToDraft(BuildContext context) async {
    final count = controller.multiSelectedCount;
    final confirmed = await showDialog<bool>(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('Move to Draft'),
        content: Text('Move $count ${count == 1 ? 'product' : 'products'} to draft status?'),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(context).pop(false),
            child: const Text('Cancel'),
          ),
          FilledButton(
            onPressed: () => Navigator.of(context).pop(true),
            child: const Text('Move to Draft'),
          ),
        ],
      ),
    );

    if (confirmed == true) {
      await controller.bulkUpdateStatus(PublishStatus.draft);
    }
  }

  /// Handles keyboard events for list navigation.
  KeyEventResult _handleKeyEvent(FocusNode node, KeyEvent event) {
    if (event is! KeyDownEvent && event is! KeyRepeatEvent) {
      return KeyEventResult.ignored;
    }

    if (event.logicalKey == LogicalKeyboardKey.arrowDown) {
      controller.selectNextDraft();
      return KeyEventResult.handled;
    }
    if (event.logicalKey == LogicalKeyboardKey.arrowUp) {
      controller.selectPreviousDraft();
      return KeyEventResult.handled;
    }

    return KeyEventResult.ignored;
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: controller,
      builder: (context, _) {
        if (controller.isLoading) {
          return const Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                CircularProgressIndicator(),
                SizedBox(height: KcSpacing.md),
                Text('Loading products…'),
              ],
            ),
          );
        }

        if (controller.error != null) {
          return Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                const Icon(Icons.error_outline, size: 48, color: KcColors.neutral),
                const SizedBox(height: KcSpacing.md),
                const Text('Failed to load product drafts.'),
                const SizedBox(height: KcSpacing.md),
                OutlinedButton.icon(
                  onPressed: controller.load,
                  icon: const Icon(Icons.refresh),
                  label: const Text('Retry'),
                ),
              ],
            ),
          );
        }

        return LayoutBuilder(
          builder: (context, constraints) {
            // On narrow screens show only the list; on wide screens show
            // a master-detail layout.
            if (constraints.maxWidth < 800) {
              return _buildDraftList();
            }
            return Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                SizedBox(width: 380, child: _buildDraftList()),
                const SizedBox(width: KcSpacing.md),
                Expanded(child: _buildPreview()),
              ],
            );
          },
        );
      },
    );
  }

  Widget _buildDraftList() {
    final count = controller.drafts.length;
    final isCompact = controller.listDensity == ListDensity.compact;

    if (count == 0) {
      return Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            const Icon(Icons.search_off, size: 48, color: KcColors.neutral),
            const SizedBox(height: KcSpacing.md),
            Text(
              controller.searchQuery.isNotEmpty || controller.activeFilter != null
                  ? 'No products match your criteria.'
                  : 'No product drafts available.',
              style: Theme.of(context).textTheme.bodyLarge?.copyWith(color: KcColors.neutral),
            ),
          ],
        ),
      );
    }

    return Focus(
      focusNode: _listFocusNode,
      onKeyEvent: _handleKeyEvent,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // ── Multi-select action bar ──────────────────────────────────
          if (controller.isMultiSelectActive)
            _MultiSelectBar(
              selectedCount: controller.multiSelectedCount,
              totalCount: count,
              onSelectAll: controller.selectAllVisible,
              onClearSelection: controller.clearMultiSelection,
              onBulkMoveToDraft: () => _confirmBulkMoveToDraft(context),
            ),
          // ── List header with count and density toggle ───────────────
          Padding(
            padding: const EdgeInsets.only(left: KcSpacing.xs, bottom: KcSpacing.sm),
            child: Row(
              children: [
                Text(
                  '$count ${count == 1 ? 'product' : 'products'}',
                  style: Theme.of(context).textTheme.bodySmall?.copyWith(color: KcColors.neutral),
                ),
                const Spacer(),
                Tooltip(
                  message: isCompact ? 'Standard view' : 'Compact view',
                  child: IconButton(
                    icon: Icon(isCompact ? Icons.view_agenda : Icons.view_headline, size: 20),
                    onPressed: controller.toggleListDensity,
                    padding: EdgeInsets.zero,
                    constraints: const BoxConstraints(),
                  ),
                ),
              ],
            ),
          ),
          Expanded(
            child: ListView.separated(
              itemCount: count,
              separatorBuilder: (_, _) => SizedBox(height: isCompact ? KcSpacing.xs : KcSpacing.sm),
              itemBuilder: (context, index) {
                final draft = controller.drafts[index];
                return SizedBox(
                  height: isCompact ? 72 : 180,
                  child: ProductDraftCard(
                    draft: draft,
                    isSelected: draft.id == controller.selectedDraft?.id,
                    onTap: () => controller.selectDraft(draft),
                    isMultiSelected: controller.isMultiSelected(draft.id),
                    onMultiSelectToggle: () => controller.toggleMultiSelect(draft.id),
                    isCompact: isCompact,
                    isStale: controller.isStale(draft),
                  ),
                );
              },
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildPreview() {
    final selected = controller.selectedDraft;
    if (selected == null) {
      return Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            const Icon(Icons.touch_app_outlined, size: 48, color: KcColors.neutral),
            const SizedBox(height: KcSpacing.md),
            Text(
              'Select a product to preview',
              style: Theme.of(context).textTheme.bodyLarge?.copyWith(color: KcColors.neutral),
            ),
          ],
        ),
      );
    }
    return ProductPreviewPanel(
      draft: selected,
      isUpdating: controller.isUpdating(selected.id),
      onPublish: () => controller.updateStatus(selected.id, PublishStatus.published),
      onMoveToDraft: () => controller.updateStatus(selected.id, PublishStatus.draft),
      onPriceChanged: (price) => controller.updatePrice(selected.id, price),
      onNameChanged: (name) => controller.updateName(selected.id, name),
      onDescriptionChanged: (desc) => controller.updateDescription(selected.id, desc),
      onCategoryChanged: (cat) => controller.updateCategory(selected.id, cat),
      onViewPolicy: widget.onViewPolicy,
    );
  }
}

/// A compact action bar shown above the product list when multi-select is
/// active. Displays the count of selected items and provides bulk actions,
/// Select All, and Clear Selection.
class _MultiSelectBar extends StatelessWidget {
  final int selectedCount;
  final int totalCount;
  final VoidCallback onSelectAll;
  final VoidCallback onClearSelection;
  final VoidCallback onBulkMoveToDraft;

  const _MultiSelectBar({
    required this.selectedCount,
    required this.totalCount,
    required this.onSelectAll,
    required this.onClearSelection,
    required this.onBulkMoveToDraft,
  });

  @override
  Widget build(BuildContext context) {
    final allSelected = selectedCount == totalCount;

    return Container(
      padding: const EdgeInsets.symmetric(horizontal: KcSpacing.sm, vertical: KcSpacing.xs),
      margin: const EdgeInsets.only(bottom: KcSpacing.sm),
      decoration: BoxDecoration(
        color: KcColors.denimBlue.withValues(alpha: 0.08),
        borderRadius: BorderRadius.circular(8),
        border: Border.all(color: KcColors.denimBlue.withValues(alpha: 0.3)),
      ),
      child: Row(
        children: [
          Icon(Icons.checklist, size: 18, color: KcColors.denimBlue),
          const SizedBox(width: KcSpacing.xs),
          Text(
            '$selectedCount selected',
            style: Theme.of(context).textTheme.bodyMedium?.copyWith(
              color: KcColors.denimBlue,
              fontWeight: FontWeight.w600,
            ),
          ),
          const SizedBox(width: KcSpacing.sm),
          OutlinedButton.icon(
            onPressed: onBulkMoveToDraft,
            icon: const Icon(Icons.drafts_outlined, size: 16),
            label: const Text('Move to Draft'),
          ),
          const Spacer(),
          if (!allSelected) TextButton(onPressed: onSelectAll, child: const Text('Select All')),
          TextButton(onPressed: onClearSelection, child: const Text('Clear')),
        ],
      ),
    );
  }
}
