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

import '../../domain/product_draft.dart';
import '../../domain/publish_status.dart';
import 'publish_status_chip.dart';

/// A detail panel that shows a full preview of the selected [ProductDraft].
///
/// Includes product image placeholder, description, metadata, and
/// status-aware action buttons:
/// - **Publish to Store** when the draft status is [PublishStatus.draft].
/// - **Move to Draft** when the draft status is [PublishStatus.published],
///   [PublishStatus.unpublished], or [PublishStatus.pendingReview].
class ProductPreviewPanel extends StatefulWidget {
  final ProductDraft draft;
  final VoidCallback? onPublish;

  /// Callback to revert a published product back to draft status.
  final VoidCallback? onMoveToDraft;

  /// Callback to update the product price. Receives the new price value.
  final ValueChanged<double>? onPriceChanged;

  /// Callback to update the product name. Receives the new name value.
  final ValueChanged<String>? onNameChanged;

  /// Callback to update the product description. Receives the new description value.
  final ValueChanged<String>? onDescriptionChanged;

  /// Callback to update the product category. Receives the new category value.
  final ValueChanged<String>? onCategoryChanged;

  /// Whether this product currently has an in-flight status update.
  /// When true, the action button is disabled and a progress indicator is shown.
  final bool isUpdating;

  /// Optional callback to navigate to the Policy page.
  final VoidCallback? onViewPolicy;

  const ProductPreviewPanel({
    super.key,
    required this.draft,
    this.onPublish,
    this.onMoveToDraft,
    this.onPriceChanged,
    this.onNameChanged,
    this.onDescriptionChanged,
    this.onCategoryChanged,
    this.isUpdating = false,
    this.onViewPolicy,
  });

  @override
  State<ProductPreviewPanel> createState() => _ProductPreviewPanelState();
}

class _ProductPreviewPanelState extends State<ProductPreviewPanel> {
  bool _editingPrice = false;
  late TextEditingController _priceController;
  String? _priceError;

  bool _editingName = false;
  late TextEditingController _nameController;
  String? _nameError;

  bool _editingDescription = false;
  late TextEditingController _descriptionController;
  String? _descriptionError;

  // ignore: prefer_final_fields
  bool _editingCategory = false;
  late TextEditingController _categoryController;
  String? _categoryError;

  @override
  void initState() {
    super.initState();
    _priceController = TextEditingController(text: widget.draft.price.toStringAsFixed(2));
    _nameController = TextEditingController(text: widget.draft.name);
    _descriptionController = TextEditingController(text: widget.draft.description);
    _categoryController = TextEditingController(text: widget.draft.category);
  }

  @override
  void didUpdateWidget(ProductPreviewPanel oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.draft.id != widget.draft.id || oldWidget.draft.price != widget.draft.price) {
      _editingPrice = false;
      _priceError = null;
      _priceController.text = widget.draft.price.toStringAsFixed(2);
    }
    if (oldWidget.draft.id != widget.draft.id || oldWidget.draft.name != widget.draft.name) {
      _editingName = false;
      _nameError = null;
      _nameController.text = widget.draft.name;
    }
    if (oldWidget.draft.id != widget.draft.id ||
        oldWidget.draft.description != widget.draft.description) {
      _editingDescription = false;
      _descriptionError = null;
      _descriptionController.text = widget.draft.description;
    }
    if (oldWidget.draft.id != widget.draft.id ||
        oldWidget.draft.category != widget.draft.category) {
      _editingCategory = false;
      _categoryError = null;
      _categoryController.text = widget.draft.category;
    }
  }

  @override
  void dispose() {
    _priceController.dispose();
    _nameController.dispose();
    _descriptionController.dispose();
    _categoryController.dispose();
    super.dispose();
  }

  void _submitPrice() {
    final parsed = double.tryParse(_priceController.text);
    if (parsed == null || parsed < 0) {
      setState(() => _priceError = 'Enter a valid price.');
      return;
    }
    setState(() {
      _priceError = null;
      _editingPrice = false;
    });
    widget.onPriceChanged?.call(parsed);
  }

  void _cancelEdit() {
    _priceController.text = widget.draft.price.toStringAsFixed(2);
    setState(() {
      _priceError = null;
      _editingPrice = false;
    });
  }

  void _submitName() {
    final trimmed = _nameController.text.trim();
    if (trimmed.isEmpty) {
      setState(() => _nameError = 'Name cannot be empty.');
      return;
    }
    setState(() {
      _nameError = null;
      _editingName = false;
    });
    widget.onNameChanged?.call(trimmed);
  }

  void _cancelNameEdit() {
    _nameController.text = widget.draft.name;
    setState(() {
      _nameError = null;
      _editingName = false;
    });
  }

  void _submitDescription() {
    final trimmed = _descriptionController.text.trim();
    if (trimmed.isEmpty) {
      setState(() => _descriptionError = 'Description cannot be empty.');
      return;
    }
    setState(() {
      _descriptionError = null;
      _editingDescription = false;
    });
    widget.onDescriptionChanged?.call(trimmed);
  }

  void _cancelDescriptionEdit() {
    _descriptionController.text = widget.draft.description;
    setState(() {
      _descriptionError = null;
      _editingDescription = false;
    });
  }

  void _submitCategory() {
    final trimmed = _categoryController.text.trim();
    if (trimmed.isEmpty) {
      setState(() => _categoryError = 'Category cannot be empty.');
      return;
    }
    setState(() {
      _categoryError = null;
      _editingCategory = false;
    });
    widget.onCategoryChanged?.call(trimmed);
  }

  void _cancelCategoryEdit() {
    _categoryController.text = widget.draft.category;
    setState(() {
      _categoryError = null;
      _editingCategory = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final draft = widget.draft;

    return KcCard(
      child: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // ── Product image ──────────────────────────────────────────
            _ProductImage(imageUrl: draft.imageUrl),
            const SizedBox(height: KcSpacing.md),

            // ── Title & status ─────────────────────────────────────────
            _buildNameRow(context),
            const SizedBox(height: KcSpacing.sm),

            // ── Metadata ───────────────────────────────────────────────
            _MetadataRow(label: 'SKU', value: draft.sku),
            _buildPriceRow(context),
            _buildCategoryRow(context),
            _MetadataRow(
              label: 'Last Modified',
              value:
                  '${draft.lastModified.year}-${draft.lastModified.month.toString().padLeft(2, '0')}-${draft.lastModified.day.toString().padLeft(2, '0')}',
            ),
            if (draft.imageUrl.isNotEmpty) _MetadataRow(label: 'Image URL', value: draft.imageUrl),
            const SizedBox(height: KcSpacing.md),

            // ── Description ────────────────────────────────────────────
            _buildDescriptionSection(context),
            const SizedBox(height: KcSpacing.xl),

            // ── Policy link ────────────────────────────────────────────
            if (widget.onViewPolicy != null) ...[
              GestureDetector(
                onTap: widget.onViewPolicy,
                child: Text(
                  'View Compliance Policy →',
                  style: theme.textTheme.bodySmall?.copyWith(
                    color: KcColors.denimBlue,
                    fontWeight: FontWeight.w600,
                  ),
                ),
              ),
              const SizedBox(height: KcSpacing.md),
            ],

            // ── Status action buttons ────────────────────────────────
            if (draft.status == PublishStatus.draft)
              SizedBox(
                width: double.infinity,
                child: FilledButton.icon(
                  onPressed: widget.isUpdating ? null : widget.onPublish,
                  icon: const Icon(Icons.publish),
                  label: const Text('Publish to Store'),
                ),
              ),
            if (draft.status == PublishStatus.published ||
                draft.status == PublishStatus.unpublished ||
                draft.status == PublishStatus.pendingReview)
              SizedBox(
                width: double.infinity,
                child: OutlinedButton.icon(
                  onPressed: widget.isUpdating ? null : widget.onMoveToDraft,
                  icon: const Icon(Icons.unpublished_outlined),
                  label: const Text('Move to Draft'),
                ),
              ),
          ],
        ),
      ),
    );
  }

  /// Builds the Name title row — either a static display with an edit
  /// icon, or an inline text field with save/cancel actions.
  Widget _buildNameRow(BuildContext context) {
    final theme = Theme.of(context);
    final draft = widget.draft;

    if (_editingName) {
      return Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              Expanded(
                child: TextField(
                  controller: _nameController,
                  enabled: !widget.isUpdating,
                  style: theme.textTheme.headlineMedium,
                  decoration: InputDecoration(
                    isDense: true,
                    contentPadding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
                    errorText: _nameError,
                  ),
                  onSubmitted: (_) => _submitName(),
                  autofocus: true,
                ),
              ),
              const SizedBox(width: KcSpacing.xs),
              IconButton(
                icon: const Icon(Icons.check, size: 20),
                onPressed: widget.isUpdating ? null : _submitName,
                tooltip: 'Save name',
                padding: const EdgeInsets.all(8),
              ),
              const SizedBox(width: KcSpacing.xs),
              IconButton(
                icon: const Icon(Icons.close, size: 20),
                onPressed: widget.isUpdating ? null : _cancelNameEdit,
                tooltip: 'Cancel',
                padding: const EdgeInsets.all(8),
              ),
            ],
          ),
        ],
      );
    }

    return Row(
      children: [
        Expanded(child: Text(draft.name, style: theme.textTheme.headlineMedium)),
        if (widget.onNameChanged != null && !widget.isUpdating) ...[
          const SizedBox(width: KcSpacing.xs),
          IconButton(
            icon: const Icon(Icons.edit, size: 18),
            onPressed: () => setState(() => _editingName = true),
            tooltip: 'Edit name',
            padding: const EdgeInsets.all(8),
          ),
        ],
        const SizedBox(width: KcSpacing.sm),
        if (widget.isUpdating)
          const SizedBox(width: 16, height: 16, child: CircularProgressIndicator(strokeWidth: 2)),
        if (widget.isUpdating) const SizedBox(width: KcSpacing.sm),
        PublishStatusChip(status: draft.status),
      ],
    );
  }

  /// Builds the Price metadata row — either a static display with an edit
  /// icon, or an inline text field with save/cancel actions.
  Widget _buildPriceRow(BuildContext context) {
    if (_editingPrice) {
      return Padding(
        padding: const EdgeInsets.symmetric(vertical: KcSpacing.xs),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              children: [
                SizedBox(
                  width: 120,
                  child: Text(
                    'Price',
                    style: Theme.of(context).textTheme.bodyMedium?.copyWith(
                      color: KcColors.neutral,
                      fontWeight: FontWeight.w600,
                    ),
                  ),
                ),
                Expanded(
                  child: TextField(
                    controller: _priceController,
                    enabled: !widget.isUpdating,
                    keyboardType: const TextInputType.numberWithOptions(decimal: true),
                    inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'[\d.]'))],
                    decoration: InputDecoration(
                      prefixText: '\$ ',
                      isDense: true,
                      contentPadding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
                      errorText: _priceError,
                    ),
                    onSubmitted: (_) => _submitPrice(),
                    autofocus: true,
                  ),
                ),
                const SizedBox(width: KcSpacing.xs),
                IconButton(
                  icon: const Icon(Icons.check, size: 20),
                  onPressed: widget.isUpdating ? null : _submitPrice,
                  tooltip: 'Save price',
                  padding: const EdgeInsets.all(8),
                ),
                const SizedBox(width: KcSpacing.xs),
                IconButton(
                  icon: const Icon(Icons.close, size: 20),
                  onPressed: widget.isUpdating ? null : _cancelEdit,
                  tooltip: 'Cancel',
                  padding: const EdgeInsets.all(8),
                ),
              ],
            ),
          ],
        ),
      );
    }

    return Padding(
      padding: const EdgeInsets.symmetric(vertical: KcSpacing.xs),
      child: Row(
        children: [
          SizedBox(
            width: 120,
            child: Text(
              'Price',
              style: Theme.of(context).textTheme.bodyMedium?.copyWith(
                color: KcColors.neutral,
                fontWeight: FontWeight.w600,
              ),
            ),
          ),
          Expanded(
            child: Text(
              '\$${widget.draft.price.toStringAsFixed(2)}',
              style: Theme.of(context).textTheme.bodyMedium,
            ),
          ),
          if (widget.onPriceChanged != null && !widget.isUpdating)
            IconButton(
              icon: const Icon(Icons.edit, size: 18),
              onPressed: () => setState(() => _editingPrice = true),
              tooltip: 'Edit price',
              padding: const EdgeInsets.all(8),
            ),
        ],
      ),
    );
  }

  /// Builds the Category metadata row — either a static display with an edit
  /// icon, or an inline text field with save/cancel actions.
  Widget _buildCategoryRow(BuildContext context) {
    if (_editingCategory) {
      return Padding(
        padding: const EdgeInsets.symmetric(vertical: KcSpacing.xs),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              children: [
                SizedBox(
                  width: 120,
                  child: Text(
                    'Category',
                    style: Theme.of(context).textTheme.bodyMedium?.copyWith(
                      color: KcColors.neutral,
                      fontWeight: FontWeight.w600,
                    ),
                  ),
                ),
                Expanded(
                  child: TextField(
                    controller: _categoryController,
                    enabled: !widget.isUpdating,
                    decoration: InputDecoration(
                      isDense: true,
                      contentPadding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
                      errorText: _categoryError,
                    ),
                    onSubmitted: (_) => _submitCategory(),
                    autofocus: true,
                  ),
                ),
                const SizedBox(width: KcSpacing.xs),
                IconButton(
                  icon: const Icon(Icons.check, size: 20),
                  onPressed: widget.isUpdating ? null : _submitCategory,
                  tooltip: 'Save category',
                  padding: const EdgeInsets.all(8),
                ),
                const SizedBox(width: KcSpacing.xs),
                IconButton(
                  icon: const Icon(Icons.close, size: 20),
                  onPressed: widget.isUpdating ? null : _cancelCategoryEdit,
                  tooltip: 'Cancel',
                  padding: const EdgeInsets.all(8),
                ),
              ],
            ),
          ],
        ),
      );
    }

    return Padding(
      padding: const EdgeInsets.symmetric(vertical: KcSpacing.xs),
      child: Row(
        children: [
          SizedBox(
            width: 120,
            child: Text(
              'Category',
              style: Theme.of(context).textTheme.bodyMedium?.copyWith(
                color: KcColors.neutral,
                fontWeight: FontWeight.w600,
              ),
            ),
          ),
          Expanded(
            child: Text(widget.draft.category, style: Theme.of(context).textTheme.bodyMedium),
          ),
          if (widget.onCategoryChanged != null && !widget.isUpdating)
            IconButton(
              icon: const Icon(Icons.edit, size: 18),
              onPressed: () => setState(() => _editingCategory = true),
              tooltip: 'Edit category',
              padding: const EdgeInsets.all(8),
            ),
        ],
      ),
    );
  }

  /// Builds the Description section — either a static display with an edit
  /// icon, or a multi-line text field with save/cancel actions.
  Widget _buildDescriptionSection(BuildContext context) {
    final theme = Theme.of(context);

    if (_editingDescription) {
      return Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              Text('Description', style: theme.textTheme.titleLarge),
              const Spacer(),
              IconButton(
                icon: const Icon(Icons.check, size: 20),
                onPressed: widget.isUpdating ? null : _submitDescription,
                tooltip: 'Save description',
                padding: const EdgeInsets.all(8),
              ),
              const SizedBox(width: KcSpacing.xs),
              IconButton(
                icon: const Icon(Icons.close, size: 20),
                onPressed: widget.isUpdating ? null : _cancelDescriptionEdit,
                tooltip: 'Cancel description edit',
                padding: const EdgeInsets.all(8),
              ),
            ],
          ),
          const SizedBox(height: KcSpacing.sm),
          TextField(
            controller: _descriptionController,
            enabled: !widget.isUpdating,
            maxLines: 5,
            minLines: 3,
            style: theme.textTheme.bodyLarge,
            decoration: InputDecoration(
              isDense: true,
              contentPadding: const EdgeInsets.all(8),
              border: const OutlineInputBorder(),
              errorText: _descriptionError,
            ),
            autofocus: true,
          ),
        ],
      );
    }

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Row(
          children: [
            Text('Description', style: theme.textTheme.titleLarge),
            if (widget.onDescriptionChanged != null && !widget.isUpdating) ...[
              const SizedBox(width: KcSpacing.xs),
              IconButton(
                icon: const Icon(Icons.edit, size: 18),
                onPressed: () => setState(() => _editingDescription = true),
                tooltip: 'Edit description',
                padding: const EdgeInsets.all(8),
              ),
            ],
          ],
        ),
        const SizedBox(height: KcSpacing.sm),
        Text(widget.draft.description, style: theme.textTheme.bodyLarge),
      ],
    );
  }
}

class _MetadataRow extends StatelessWidget {
  final String label;
  final String value;

  const _MetadataRow({required this.label, required this.value});

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: KcSpacing.xs),
      child: Row(
        children: [
          SizedBox(
            width: 120,
            child: Text(
              label,
              style: Theme.of(context).textTheme.bodyMedium?.copyWith(
                color: KcColors.neutral,
                fontWeight: FontWeight.w600,
              ),
            ),
          ),
          Expanded(child: Text(value, style: Theme.of(context).textTheme.bodyMedium)),
        ],
      ),
    );
  }
}

/// Displays the product image when [imageUrl] is non-empty, falling back to a
/// placeholder icon when no URL is available.
class _ProductImage extends StatelessWidget {
  final String imageUrl;

  const _ProductImage({required this.imageUrl});

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 180,
      width: double.infinity,
      decoration: BoxDecoration(
        color: KcColors.background,
        borderRadius: BorderRadius.circular(12),
        border: Border.all(color: KcColors.border),
      ),
      clipBehavior: Clip.antiAlias,
      child: imageUrl.isEmpty
          ? const Center(child: Icon(Icons.image_outlined, size: 48, color: KcColors.neutral))
          : Image.network(
              imageUrl,
              fit: BoxFit.cover,
              errorBuilder: (_, _, _) => const Center(
                child: Icon(Icons.broken_image_outlined, size: 48, color: KcColors.neutral),
              ),
            ),
    );
  }
}
