import 'dart:async';

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

import '../../../../../widgets/components/superport_detail_dialog.dart';
import '../../../vendor/domain/entities/vendor.dart';

/// 벤더 상세 다이얼로그에서 발생한 사용자 액션 종류이다.
enum VendorDetailDialogAction { created, updated, deleted, restored }

/// 벤더 상세 다이얼로그 결과를 담는 모델이다.
class VendorDetailDialogResult {
  const VendorDetailDialogResult({required this.action, required this.message});

  final VendorDetailDialogAction action;
  final String message;
}

typedef VendorCreateCallback = Future<Vendor?> Function(VendorInput input);
typedef VendorUpdateCallback =
    Future<Vendor?> Function(int id, VendorInput input);
typedef VendorDeleteCallback = Future<bool> Function(int id);
typedef VendorRestoreCallback = Future<Vendor?> Function(int id);

/// 벤더 상세 다이얼로그를 표시한다.
Future<VendorDetailDialogResult?> showVendorDetailDialog({
  required BuildContext context,
  required intl.DateFormat dateFormat,
  Vendor? vendor,
  required VendorCreateCallback onCreate,
  required VendorUpdateCallback onUpdate,
  required VendorDeleteCallback onDelete,
  required VendorRestoreCallback onRestore,
}) {
  final metadata = vendor == null
      ? const <SuperportDetailMetadata>[]
      : [
          SuperportDetailMetadata.text(
            label: 'ID',
            value: vendor.id?.toString() ?? '-',
          ),
          SuperportDetailMetadata.text(label: '코드', value: vendor.vendorCode),
          SuperportDetailMetadata.text(
            label: '상태',
            value: vendor.isActive ? '사용중' : '미사용',
          ),
          SuperportDetailMetadata.text(
            label: '삭제 상태',
            value: vendor.isDeleted ? '삭제됨' : '정상',
          ),
          SuperportDetailMetadata.text(
            label: '생성일시',
            value: vendor.createdAt == null
                ? '-'
                : dateFormat.format(vendor.createdAt!.toLocal()),
          ),
          SuperportDetailMetadata.text(
            label: '변경일시',
            value: vendor.updatedAt == null
                ? '-'
                : dateFormat.format(vendor.updatedAt!.toLocal()),
          ),
          SuperportDetailMetadata.text(
            label: '비고',
            value: vendor.note?.isEmpty ?? true ? '-' : vendor.note!,
          ),
        ];

  return showSuperportDetailDialog<VendorDetailDialogResult>(
    context: context,
    title: vendor == null ? '벤더 등록' : '벤더 상세',
    description: vendor == null
        ? '새로운 벤더 정보를 입력하세요.'
        : '벤더 기본 정보와 상태를 확인하고 관리합니다.',
    sections: [
      _VendorEditSection(
        id: vendor == null
            ? _VendorDetailSections.create
            : _VendorDetailSections.edit,
        label: vendor == null ? '등록' : '수정',
        vendor: vendor,
        onSubmit: (input) async {
          if (vendor == null) {
            final created = await onCreate(input);
            if (created == null) {
              return null;
            }
            return VendorDetailDialogResult(
              action: VendorDetailDialogAction.created,
              message: '벤더를 등록했습니다.',
            );
          }
          final updated = await onUpdate(vendor.id!, input);
          if (updated == null) {
            return null;
          }
          return VendorDetailDialogResult(
            action: VendorDetailDialogAction.updated,
            message: '벤더를 수정했습니다.',
          );
        },
      ),
      if (vendor != null)
        SuperportDetailDialogSection(
          id: vendor.isDeleted
              ? _VendorDetailSections.restore
              : _VendorDetailSections.delete,
          label: vendor.isDeleted ? '복구' : '삭제',
          icon: vendor.isDeleted ? LucideIcons.history : LucideIcons.trash2,
          builder: (_) => _VendorDangerSection(
            vendor: vendor,
            onDelete: () async {
              final success = await onDelete(vendor.id!);
              if (!success) {
                return null;
              }
              return VendorDetailDialogResult(
                action: VendorDetailDialogAction.deleted,
                message: '벤더를 삭제했습니다.',
              );
            },
            onRestore: () async {
              final restored = await onRestore(vendor.id!);
              if (restored == null) {
                return null;
              }
              return VendorDetailDialogResult(
                action: VendorDetailDialogAction.restored,
                message: '벤더를 복구했습니다.',
              );
            },
          ),
        ),
    ],
    summary: vendor == null
        ? null
        : Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                vendor.vendorName,
                style: ShadTheme.of(context).textTheme.h4,
              ),
            ],
          ),
    summaryBadges: vendor == null
        ? const []
        : [
            if (vendor.isActive)
              const ShadBadge(child: Text('사용중'))
            else
              const ShadBadge.outline(child: Text('미사용')),
            if (vendor.isDeleted)
              const ShadBadge.destructive(child: Text('삭제됨')),
          ],
    metadata: metadata,
    emptyPlaceholder: const Text('표시할 상세 정보가 없습니다.'),
    initialSectionId: vendor == null
        ? _VendorDetailSections.create
        : _VendorDetailSections.edit,
  );
}

/// 다이얼로그 섹션 ID 모음.
class _VendorDetailSections {
  static const edit = 'edit';
  static const delete = 'delete';
  static const restore = 'restore';
  static const create = 'create';
}

/// 벤더 등록/수정 폼 섹션이다.
class _VendorEditSection extends SuperportDetailDialogSection {
  _VendorEditSection({
    required super.id,
    required super.label,
    required this.vendor,
    required this.onSubmit,
  }) : super(
         icon: LucideIcons.pencil,
         builder: (context) => _VendorForm(vendor: vendor, onSubmit: onSubmit),
       );

  final Vendor? vendor;
  final Future<VendorDetailDialogResult?> Function(VendorInput input) onSubmit;
}

/// 삭제/복구를 안내하는 위험 섹션이다.
class _VendorDangerSection extends StatelessWidget {
  const _VendorDangerSection({
    required this.vendor,
    required this.onDelete,
    required this.onRestore,
  });

  final Vendor vendor;
  final Future<VendorDetailDialogResult?> Function() onDelete;
  final Future<VendorDetailDialogResult?> Function() onRestore;

  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);
    final isDeleted = vendor.isDeleted;
    final description = isDeleted
        ? '벤더를 복구하면 다시 목록에 노출되고 신규 트랜잭션에서 선택이 가능합니다.'
        : '삭제하면 벤더가 목록에서 숨겨지고 관련 데이터는 보존됩니다.';
    final confirmLabel = isDeleted ? '복구' : '삭제';

    return Padding(
      padding: const EdgeInsets.only(top: 8),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(description, style: theme.textTheme.small),
          const SizedBox(height: 16),
          if (isDeleted)
            ShadButton(
              onPressed: () async {
                final navigator = Navigator.of(context, rootNavigator: true);
                final result = await onRestore();
                if (result != null && navigator.mounted) {
                  navigator.pop(result);
                }
              },
              child: Text(confirmLabel),
            )
          else
            ShadButton.destructive(
              onPressed: () async {
                final navigator = Navigator.of(context, rootNavigator: true);
                final result = await onDelete();
                if (result != null && navigator.mounted) {
                  navigator.pop(result);
                }
              },
              child: Text(confirmLabel),
            ),
        ],
      ),
    );
  }
}

/// 벤더 입력 폼을 담당하는 위젯이다.
class _VendorForm extends StatefulWidget {
  const _VendorForm({required this.vendor, required this.onSubmit});

  final Vendor? vendor;
  final Future<VendorDetailDialogResult?> Function(VendorInput input) onSubmit;

  @override
  State<_VendorForm> createState() => _VendorFormState();
}

class _VendorFormState extends State<_VendorForm> {
  late final TextEditingController _codeController;
  late final TextEditingController _nameController;
  late final TextEditingController _noteController;
  late final ValueNotifier<bool> _isActiveNotifier;
  String? _codeError;
  String? _nameError;
  String? _submitError;
  bool _isSubmitting = false;

  bool get _isEdit => widget.vendor != null;

  @override
  void initState() {
    super.initState();
    _codeController = TextEditingController(
      text: widget.vendor?.vendorCode ?? '',
    );
    _nameController = TextEditingController(
      text: widget.vendor?.vendorName ?? '',
    );
    _noteController = TextEditingController(text: widget.vendor?.note ?? '');
    _isActiveNotifier = ValueNotifier<bool>(widget.vendor?.isActive ?? true);
  }

  @override
  void dispose() {
    _codeController.dispose();
    _nameController.dispose();
    _noteController.dispose();
    _isActiveNotifier.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        _VendorFormField(
          label: '벤더코드',
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              ShadInput(
                controller: _codeController,
                readOnly: _isEdit,
                onChanged: (_) {
                  if (_codeController.text.trim().isNotEmpty) {
                    setState(() {
                      _codeError = null;
                    });
                  }
                },
              ),
              if (_codeError != null)
                Padding(
                  padding: const EdgeInsets.only(top: 6),
                  child: Text(
                    _codeError!,
                    style: theme.textTheme.small.copyWith(
                      color: theme.colorScheme.destructive,
                    ),
                  ),
                ),
            ],
          ),
        ),
        const SizedBox(height: 16),
        _VendorFormField(
          label: '벤더명',
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              ShadInput(
                controller: _nameController,
                onChanged: (_) {
                  if (_nameController.text.trim().isNotEmpty) {
                    setState(() {
                      _nameError = null;
                    });
                  }
                },
              ),
              if (_nameError != null)
                Padding(
                  padding: const EdgeInsets.only(top: 6),
                  child: Text(
                    _nameError!,
                    style: theme.textTheme.small.copyWith(
                      color: theme.colorScheme.destructive,
                    ),
                  ),
                ),
            ],
          ),
        ),
        const SizedBox(height: 16),
        _VendorFormField(
          label: '사용 여부',
          child: ValueListenableBuilder<bool>(
            valueListenable: _isActiveNotifier,
            builder: (_, value, __) {
              return ShadSwitch(
                value: value,
                onChanged: _isSubmitting
                    ? null
                    : (next) => _isActiveNotifier.value = next,
              );
            },
          ),
        ),
        const SizedBox(height: 16),
        _VendorFormField(
          label: '비고',
          child: ShadTextarea(
            controller: _noteController,
            minHeight: 96,
            maxHeight: 200,
          ),
        ),
        if (_submitError != null) ...[
          const SizedBox(height: 16),
          Text(
            _submitError!,
            style: theme.textTheme.small.copyWith(
              color: theme.colorScheme.destructive,
            ),
          ),
        ],
        const SizedBox(height: 20),
        Align(
          alignment: Alignment.centerRight,
          child: ShadButton(
            onPressed: _isSubmitting ? null : _handleSubmit,
            child: Text(_isEdit ? '저장' : '등록'),
          ),
        ),
      ],
    );
  }

  Future<void> _handleSubmit() async {
    final code = _codeController.text.trim();
    final name = _nameController.text.trim();

    setState(() {
      _codeError = code.isEmpty ? '벤더코드를 입력하세요.' : null;
      _nameError = name.isEmpty ? '벤더명을 입력하세요.' : null;
      _submitError = null;
    });

    if (_codeError != null || _nameError != null) {
      return;
    }

    setState(() {
      _isSubmitting = true;
    });

    final input = VendorInput(
      vendorCode: code,
      vendorName: name,
      isActive: _isActiveNotifier.value,
      note: _noteController.text.trim().isEmpty
          ? null
          : _noteController.text.trim(),
    );
    final navigator = Navigator.of(context, rootNavigator: true);
    final result = await widget.onSubmit(input);

    if (!mounted) {
      return;
    }

    setState(() {
      _isSubmitting = false;
      _submitError = result == null ? '요청 처리에 실패했습니다.' : null;
    });

    if (result != null && navigator.mounted) {
      navigator.pop(result);
    }
  }
}

/// 벤더 폼 필드 레이블/컨텐츠 레이아웃을 제공한다.
class _VendorFormField extends StatelessWidget {
  const _VendorFormField({required this.label, required this.child});

  final String label;
  final Widget child;

  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(label, style: theme.textTheme.small),
        const SizedBox(height: 6),
        child,
      ],
    );
  }
}

/// 요약 섹션에서 사용할 단순 키-값 모델이다.
