import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import '../models/customer_model.dart';
import '../models/invoice_models.dart';
import '../services/pdf_generator.dart';
import '../services/invoice_repository.dart';
import '../services/customer_repository.dart';
import '../widgets/invoice_pdf_preview_page.dart';
import '../services/gps_service.dart';
import 'customer_master_screen.dart';
import 'product_master_screen.dart';
import '../models/product_model.dart';
import '../services/app_settings_repository.dart';
import '../services/edit_log_repository.dart';

class InvoiceInputForm extends StatefulWidget {
  final Function(Invoice invoice, String filePath) onInvoiceGenerated;
  final Invoice? existingInvoice; // 追加: 編集時の既存伝票
  final DocumentType initialDocumentType;
  final bool startViewMode;
  final bool showNewBadge;
  final bool showCopyBadge;

  const InvoiceInputForm({
    super.key,
    required this.onInvoiceGenerated,
    this.existingInvoice, // 追加
    this.initialDocumentType = DocumentType.invoice,
    this.startViewMode = true,
    this.showNewBadge = false,
    this.showCopyBadge = false,
  });

  @override
  State<InvoiceInputForm> createState() => _InvoiceInputFormState();
}

List<InvoiceItem> _cloneItems(List<InvoiceItem> source, {bool resetIds = false}) {
  return source
      .map((e) => InvoiceItem(
            id: resetIds ? null : e.id,
            productId: e.productId,
            description: e.description,
            quantity: e.quantity,
            unitPrice: e.unitPrice,
          ))
      .toList(growable: true);
}

class _InvoiceInputFormState extends State<InvoiceInputForm> {
  final _repository = InvoiceRepository();
  final InvoiceRepository _invoiceRepo = InvoiceRepository();
  Customer? _selectedCustomer;
  final List<InvoiceItem> _items = [];
  double _taxRate = 0.10;
  bool _includeTax = false;
  DocumentType _documentType = DocumentType.invoice; // 追加
  DateTime _selectedDate = DateTime.now(); // 追加: 伝票日付
  bool _isDraft = true; // デフォルトは下書き
  final TextEditingController _subjectController = TextEditingController(); // 追加
  bool _isSaving = false; // 保存中フラグ
  String? _currentId; // 保存対象のID（コピー時に新規になる）
  bool _isLocked = false;
  final List<_InvoiceSnapshot> _undoStack = [];
  final List<_InvoiceSnapshot> _redoStack = [];
  bool _isApplyingSnapshot = false;
  bool get _canUndo => _undoStack.length > 1;
  bool get _canRedo => _redoStack.isNotEmpty;
  bool _isViewMode = true; // デフォルトでビューワ
  bool _summaryIsBlue = false; // デフォルトは白
  final AppSettingsRepository _settingsRepo = AppSettingsRepository();
  bool _showNewBadge = false;
  bool _showCopyBadge = false;
  final EditLogRepository _editLogRepo = EditLogRepository();
  List<EditLogEntry> _editLogs = [];
  final FocusNode _subjectFocusNode = FocusNode();
  String _lastLoggedSubject = "";
  bool _hasUnsavedChanges = false;

  String _documentTypeLabel(DocumentType type) {
    switch (type) {
      case DocumentType.estimation:
        return "見積書";
      case DocumentType.delivery:
        return "納品書";
      case DocumentType.invoice:
        return "請求書";
      case DocumentType.receipt:
        return "領収書";
    }
  }

  Color _documentTypeColor(DocumentType type) {
    switch (type) {
      case DocumentType.estimation:
        return Colors.blue;
      case DocumentType.delivery:
        return Colors.teal;
      case DocumentType.invoice:
        return Colors.indigo;
      case DocumentType.receipt:
        return Colors.green;
    }
  }

  String _customerNameWithHonorific(Customer customer) {
    final base = customer.formalName;
    final hasHonorific = RegExp(r'(様|御中|殿)$').hasMatch(base);
    return hasHonorific ? base : "$base ${customer.title}";
  }

  String _ensureCurrentId() {
    _currentId ??= DateTime.now().millisecondsSinceEpoch.toString();
    return _currentId!;
  }

  Future<bool> _confirmDiscardChanges() async {
    if (!_hasUnsavedChanges || _isSaving) {
      return true;
    }
    final result = await showDialog<bool>(
      context: context,
      barrierDismissible: false,
      builder: (context) => AlertDialog(
        title: const Text('保存されていない変更があります'),
        content: const Text('編集した内容を破棄してもよろしいですか？'),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(context).pop(false),
            child: const Text('編集を続ける'),
          ),
          FilledButton(
            onPressed: () => Navigator.of(context).pop(true),
            child: const Text('破棄する'),
          ),
        ],
      ),
    );
    return result ?? false;
  }

  Future<void> _handleBackPressed() async {
    final allow = await _confirmDiscardChanges();
    if (!mounted || !allow) return;
    Navigator.of(context).maybePop();
  }

  Future<DocumentType?> _pickCopyDocumentType() {
    return showDialog<DocumentType>(
      context: context,
      builder: (context) => SimpleDialog(
        title: const Text('コピー後の伝票種別を選択'),
        children: DocumentType.values.map((type) {
          final isCurrent = type == _documentType;
          return SimpleDialogOption(
            onPressed: () => Navigator.of(context).pop(type),
            child: Row(
              children: [
                Icon(
                  isCurrent ? Icons.check_circle : Icons.circle_outlined,
                  color: _documentTypeColor(type),
                ),
                const SizedBox(width: 12),
                Text(_documentTypeLabel(type)),
              ],
            ),
          );
        }).toList(),
      ),
    );
  }

  Future<void> _copyAsNew() async {
    if (widget.existingInvoice == null && _currentId == null) return;
    final selectedType = await _pickCopyDocumentType();
    if (selectedType == null) return;
    final clonedItems = _cloneItems(_items, resetIds: true);
    setState(() {
      _currentId = DateTime.now().millisecondsSinceEpoch.toString();
      _isDraft = true;
      _isLocked = false;
      _selectedDate = DateTime.now();
      _documentType = selectedType;
      _items
        ..clear()
        ..addAll(clonedItems);
      _isViewMode = false;
      _showCopyBadge = true;
      _showNewBadge = false;
      _pushHistory(clearRedo: true);
      _editLogs.clear();
    });
  }

  @override
  void initState() {
    super.initState();
    _subjectController.addListener(_onSubjectChanged);
    _subjectFocusNode.addListener(() {
      if (!_subjectFocusNode.hasFocus) {
        final current = _subjectController.text;
        if (current != _lastLoggedSubject) {
          final id = _ensureCurrentId();
          final msg = "件名を『$current』に更新しました";
          _editLogRepo.addLog(id, msg).then((_) => _loadEditLogs());
          _lastLoggedSubject = current;
        }
      }
    });
    _subjectController.addListener(_onSubjectChanged);
    _loadInitialData();
  }

  Future<void> _loadInitialData() async {
    _repository.cleanupOrphanedPdfs();
    final customerRepo = CustomerRepository();
    await customerRepo.getAllCustomers();

    final savedSummary = await _settingsRepo.getSummaryTheme();
    _summaryIsBlue = savedSummary == 'blue';

    _isApplyingSnapshot = true;
    setState(() {
      // 既存伝票がある場合は初期値を上書き
      if (widget.existingInvoice != null) {
        final inv = widget.existingInvoice!;
        _selectedCustomer = inv.customer;
        _items.addAll(inv.items);
        _taxRate = inv.taxRate;
        _includeTax = inv.taxRate > 0;
        _documentType = inv.documentType;
        _selectedDate = inv.date;
        _isDraft = inv.isDraft;
        _currentId = inv.id;
        _isLocked = inv.isLocked;
        if (inv.subject != null) _subjectController.text = inv.subject!;
      } else {
        _taxRate = 0;
        _includeTax = false;
        _isDraft = true;
        _documentType = widget.initialDocumentType;
        _currentId = null;
        _isLocked = false;
      }
    });
    _isApplyingSnapshot = false;
    _isViewMode = widget.startViewMode; // 指定に従う
    _showNewBadge = widget.showNewBadge;
    _showCopyBadge = widget.showCopyBadge;
    _pushHistory(clearRedo: true, markDirty: false);
    if (_hasUnsavedChanges) {
      setState(() => _hasUnsavedChanges = false);
    }
    _lastLoggedSubject = _subjectController.text;
    if (_currentId != null) {
      _loadEditLogs();
    }
  }

  @override
  void dispose() {
    _subjectFocusNode.dispose();
    super.dispose();
  }

  Future<void> _loadEditLogs() async {
    if (_currentId == null) return;
    final logs = await _editLogRepo.getLogs(_currentId!);
    if (!mounted) return;
    setState(() => _editLogs = logs);
  }

  void _onSubjectChanged() {
    if (_isApplyingSnapshot) return;
    _pushHistory();
  }

  void _addItem() {
    Navigator.push<Product>(
      context,
      MaterialPageRoute(builder: (_) => const ProductMasterScreen(selectionMode: true)),
    ).then((product) {
      if (product == null) return;
      setState(() {
        _items.add(InvoiceItem(
          productId: product.id,
          description: product.name,
          quantity: 1,
          unitPrice: product.defaultUnitPrice,
        ));
      });
      _pushHistory();
      final id = _ensureCurrentId();
      final msg = "商品「${product.name}」を追加しました";
      _editLogRepo.addLog(id, msg).then((_) => _loadEditLogs());
    });
  }

  int get _subTotal => _items.fold(0, (sum, item) => sum + (item.unitPrice * item.quantity));
  Future<void> _saveInvoice({bool generatePdf = true}) async {
    if (_selectedCustomer == null) {
      ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("取引先を選択してください")));
      return;
    }
    if (_items.isEmpty) {
      ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("明細を1件以上入力してください")));
      return;
    }

    // GPS情報の取得
    final gpsService = GpsService();
    final pos = await gpsService.getCurrentLocation();
    if (pos != null) {
      await gpsService.logLocation(); // 履歴テーブルにも保存
    }

    final invoiceId = _ensureCurrentId();

    final invoice = Invoice(
      id: invoiceId,
      customer: _selectedCustomer!,
      date: _selectedDate,
      items: _items,
      taxRate: _includeTax ? _taxRate : 0.0,
      documentType: _documentType,
      customerFormalNameSnapshot: _selectedCustomer!.formalName,
      subject: _subjectController.text.isNotEmpty ? _subjectController.text : null, // 追加
      notes: _includeTax ? "（消費税 ${(_taxRate * 100).toInt()}% 込み）" : null,
      latitude: pos?.latitude,
      longitude: pos?.longitude,
      isDraft: _isDraft, // 追加
    );

    setState(() => _isSaving = true);
    try {
      // PDF生成有無に関わらず、まずは保存
      if (generatePdf) {
        final path = await generateInvoicePdf(invoice);
        if (path != null) {
          final updatedInvoice = invoice.copyWith(filePath: path);
          await _repository.saveInvoice(updatedInvoice);
          _currentId = updatedInvoice.id;
          if (mounted) widget.onInvoiceGenerated(updatedInvoice, path);
          if (mounted) ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("伝票を保存し、PDFを生成しました")));
        } else {
          if (mounted) ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("PDF生成に失敗しました")));
        }
      } else {
        await _repository.saveInvoice(invoice);
        _currentId = invoice.id;
        if (mounted) ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("伝票を保存しました（PDF未生成）")));
      }
      await _editLogRepo.addLog(_currentId!, "伝票を保存しました");
      await _loadEditLogs();
      if (mounted) {
        setState(() {
          _isViewMode = true;
          _hasUnsavedChanges = false;
        });
      }
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('保存に失敗しました: $e')));
      }
    } finally {
      if (mounted) setState(() => _isSaving = false);
    }
  }

  void _showPreview() {
    if (_selectedCustomer == null) return;
    final id = _ensureCurrentId();
    _editLogRepo.addLog(id, "PDFプレビューを開きました").then((_) => _loadEditLogs());
    final invoice = Invoice(
      id: id,
      customer: _selectedCustomer!,
      date: _selectedDate, // 修正
      items: _items,
      taxRate: _includeTax ? _taxRate : 0.0,
      documentType: _documentType,
      customerFormalNameSnapshot: _selectedCustomer!.formalName,
      notes: _includeTax ? "（消費税 ${(_taxRate * 100).toInt()}% 込み）" : "（非課税）",
      isDraft: _isDraft,
      isLocked: _isLocked,
    );

    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) => InvoicePdfPreviewPage(
          invoice: invoice,
          isUnlocked: true,
          isLocked: _isLocked,
          allowFormalIssue: invoice.isDraft && !_isLocked,
          onFormalIssue: invoice.isDraft
              ? () async {
                  final promoted = invoice.copyWith(id: id, isDraft: false, isLocked: true);
                  await _invoiceRepo.saveInvoice(promoted);
                  final newPath = await generateInvoicePdf(promoted);
                  final saved = newPath != null ? promoted.copyWith(filePath: newPath) : promoted;
                  await _invoiceRepo.saveInvoice(saved);
                  await _editLogRepo.addLog(_ensureCurrentId(), "正式発行しました");
                  if (!context.mounted) return false;
                  setState(() {
                    _isDraft = false;
                    _isLocked = true;
                  });
                  return true;
                }
              : null,
          showShare: true,
          showEmail: true,
          showPrint: true,
        ),
      ),
    );
  }

  void _pushHistory({bool clearRedo = false, bool markDirty = true}) {
    setState(() {
      if (_undoStack.length >= 30) _undoStack.removeAt(0);
      _undoStack.add(_InvoiceSnapshot(
        customer: _selectedCustomer,
        items: _cloneItems(_items),
        taxRate: _taxRate,
        includeTax: _includeTax,
        documentType: _documentType,
        date: _selectedDate,
        isDraft: _isDraft,
        subject: _subjectController.text,
      ));
      if (clearRedo) _redoStack.clear();
      if (markDirty) {
        _hasUnsavedChanges = true;
      }
    });
  }

  void _undo() {
    if (_undoStack.length <= 1) return; // 直前状態がない
    setState(() {
      // 現在の状態をredoへ積む
      _redoStack.add(_InvoiceSnapshot(
        customer: _selectedCustomer,
        items: _cloneItems(_items),
        taxRate: _taxRate,
        includeTax: _includeTax,
        documentType: _documentType,
        date: _selectedDate,
        isDraft: _isDraft,
        subject: _subjectController.text,
      ));
      // 一番新しい履歴を捨て、直前のスナップショットを適用
      _undoStack.removeLast();
      final snapshot = _undoStack.last;
      _isApplyingSnapshot = true;
      _selectedCustomer = snapshot.customer;
      _items
        ..clear()
        ..addAll(_cloneItems(snapshot.items));
      _taxRate = snapshot.taxRate;
      _includeTax = snapshot.includeTax;
      _documentType = snapshot.documentType;
      _selectedDate = snapshot.date;
      _isDraft = snapshot.isDraft;
      _subjectController.text = snapshot.subject;
      _isApplyingSnapshot = false;
    });
  }

  void _redo() {
    if (_redoStack.isEmpty) return;
    setState(() {
      _undoStack.add(_InvoiceSnapshot(
        customer: _selectedCustomer,
        items: _cloneItems(_items),
        taxRate: _taxRate,
        includeTax: _includeTax,
        documentType: _documentType,
        date: _selectedDate,
        isDraft: _isDraft,
        subject: _subjectController.text,
      ));
      final snapshot = _redoStack.removeLast();
      _isApplyingSnapshot = true;
      _selectedCustomer = snapshot.customer;
      _items
        ..clear()
        ..addAll(_cloneItems(snapshot.items));
      _taxRate = snapshot.taxRate;
      _includeTax = snapshot.includeTax;
      _documentType = snapshot.documentType;
      _selectedDate = snapshot.date;
      _isDraft = snapshot.isDraft;
      _subjectController.text = snapshot.subject;
      _isApplyingSnapshot = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    final fmt = NumberFormat("#,###");
    final themeColor = Theme.of(context).scaffoldBackgroundColor;
    final textColor = Colors.black87;

    final docColor = _documentTypeColor(_documentType);

    return PopScope(
      canPop: false,
      onPopInvokedWithResult: (didPop, result) async {
        if (didPop) return;
        final allow = await _confirmDiscardChanges();
        if (allow && context.mounted) {
          Navigator.of(context).pop(result);
        }
      },
      child: Scaffold(
        backgroundColor: themeColor,
        resizeToAvoidBottomInset: false,
        appBar: AppBar(
          backgroundColor: docColor,
          leading: IconButton(
            icon: const Icon(Icons.arrow_back),
            onPressed: () => _handleBackPressed(),
          ),
          title: Text("A1:${_documentTypeLabel(_documentType)}"),
          actions: [
            if (_isDraft)
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 10),
                child: _DraftBadge(),
              ),
            IconButton(
              icon: const Icon(Icons.copy),
              tooltip: "コピーして新規",
              onPressed: () => _copyAsNew(),
            ),
            if (_isLocked)
              const Padding(
                padding: EdgeInsets.symmetric(horizontal: 8),
                child: Icon(Icons.lock, color: Colors.white),
              )
            else if (_isViewMode)
              IconButton(
                icon: const Icon(Icons.edit),
                tooltip: "編集モードにする",
                onPressed: () => setState(() => _isViewMode = false),
              )
            else ...[
              IconButton(
                icon: const Icon(Icons.undo),
                onPressed: _canUndo ? _undo : null,
                tooltip: "元に戻す",
              ),
              IconButton(
                icon: const Icon(Icons.redo),
                onPressed: _canRedo ? _redo : null,
                tooltip: "やり直す",
              ),
              if (!_isLocked)
                IconButton(
                  icon: const Icon(Icons.save),
                  tooltip: "保存",
                  onPressed: _isSaving ? null : () => _saveInvoice(generatePdf: false),
                ),
            ],
          ],
        ),
        body: Stack(
          children: [
            Column(
              children: [
                Expanded(
                  child: SingleChildScrollView(
                    padding: EdgeInsets.fromLTRB(16, 16, 16, MediaQuery.of(context).viewInsets.bottom + 140),
                    keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        _buildDateSection(),
                        const SizedBox(height: 16),
                        _buildCustomerSection(),
                        const SizedBox(height: 16),
                        _buildSubjectSection(textColor),
                        const SizedBox(height: 20),
                        _buildItemsSection(fmt),
                        const SizedBox(height: 20),
                        _buildSummarySection(fmt),
                        const SizedBox(height: 12),
                        _buildEditLogsSection(),
                        const SizedBox(height: 20),
                      ],
                    ),
                  ),
                ),
                _buildBottomActionBar(),
              ],
            ),
            if (_isSaving)
              Container(
                color: Colors.black54,
                child: const Center(
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      CircularProgressIndicator(color: Colors.white),
                      SizedBox(height: 16),
                      Text("保存中...", style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold)),
                    ],
                  ),
                ),
              ),
          ],
        ),
      ),
    );
  }

  Widget _buildDateSection() {
    final fmt = DateFormat('yyyy/MM/dd');
    return GestureDetector(
      onTap: _isViewMode
          ? null
          : () async {
              final picked = await showDatePicker(
                context: context,
                initialDate: _selectedDate,
                firstDate: DateTime(2000),
                lastDate: DateTime(2100),
              );
              if (picked != null) {
                setState(() => _selectedDate = picked);
                _pushHistory();
              }
            },
      child: Align(
        alignment: Alignment.centerLeft,
        child: Container(
          padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
          decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.circular(12),
            boxShadow: [BoxShadow(color: Colors.black.withValues(alpha: 0.06), blurRadius: 8, offset: const Offset(0, 3))],
          ),
          child: Row(
            mainAxisSize: MainAxisSize.min,
            children: [
              const Icon(Icons.calendar_today, size: 18, color: Colors.indigo),
              const SizedBox(width: 8),
              Text("伝票日付: ${fmt.format(_selectedDate)}", style: const TextStyle(fontWeight: FontWeight.bold)),
              if (_showNewBadge)
                Container(
                  margin: const EdgeInsets.only(left: 8),
                  padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
                  decoration: BoxDecoration(
                    color: Colors.orange.shade100,
                    borderRadius: BorderRadius.circular(10),
                  ),
                  child: const Text("新規", style: TextStyle(color: Colors.deepOrange, fontSize: 11, fontWeight: FontWeight.bold)),
                ),
              if (_showCopyBadge)
                Container(
                  margin: const EdgeInsets.only(left: 8),
                  padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
                  decoration: BoxDecoration(
                    color: Colors.blue.shade100,
                    borderRadius: BorderRadius.circular(10),
                  ),
                  child: const Text("複写", style: TextStyle(color: Colors.blue, fontSize: 11, fontWeight: FontWeight.bold)),
                ),
              if (!_isViewMode && !_isLocked) ...[
                const SizedBox(width: 8),
                const Icon(Icons.chevron_right, size: 18, color: Colors.indigo),
              ],
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildCustomerSection() {
    return Container(
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(12),
        boxShadow: [BoxShadow(color: Colors.black.withValues(alpha: 0.06), blurRadius: 8, offset: const Offset(0, 3))],
      ),
      child: ListTile(
        leading: const Icon(Icons.business, color: Colors.blueGrey),
        title: Text(
            _selectedCustomer != null ? _customerNameWithHonorific(_selectedCustomer!) : "取引先を選択してください",
            style: TextStyle(color: _selectedCustomer == null ? Colors.grey : Colors.black87, fontWeight: FontWeight.bold)),
        subtitle: _isViewMode ? null : const Text("顧客マスターから選択"),
        trailing: (_isViewMode || _isLocked) ? null : const Icon(Icons.chevron_right),
        onTap: (_isViewMode || _isLocked)
            ? null
            : () async {
                final Customer? picked = await Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (_) => CustomerMasterScreen(selectionMode: true),
                    fullscreenDialog: true,
                  ),
                );
                if (picked != null) {
                  setState(() => _selectedCustomer = picked);
                  _pushHistory();
                }
              },
      ),
    );
  }

  Widget _buildItemsSection(NumberFormat fmt) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            const Text("明細項目", style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
            if (!_isViewMode && !_isLocked)
              TextButton.icon(onPressed: _addItem, icon: const Icon(Icons.add), label: const Text("追加")),
          ],
        ),
        if (_items.isEmpty)
          const Padding(
            padding: EdgeInsets.symmetric(vertical: 20),
            child: Center(child: Text("商品が追加されていません", style: TextStyle(color: Colors.grey))),
          )
        else if (_isViewMode)
          Column(
            children: _items
                .map((item) => Card(
                      margin: const EdgeInsets.only(bottom: 6),
                      elevation: 0.5,
                      child: ListTile(
                        dense: true,
                        contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
                        title: Text(item.description, style: const TextStyle(fontSize: 13.5)),
                        subtitle: Text("￥${fmt.format(item.unitPrice)} x ${item.quantity}", style: const TextStyle(fontSize: 12.5)),
                        trailing: Text(
                          "￥${fmt.format(item.unitPrice * item.quantity)}",
                          style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 13.5),
                        ),
                      ),
                    ))
                .toList(),
          )
        else
          ReorderableListView.builder(
            shrinkWrap: true,
            physics: const NeverScrollableScrollPhysics(),
            itemCount: _items.length,
            onReorder: (oldIndex, newIndex) async {
              int targetIndex = newIndex;
              setState(() {
                if (targetIndex > oldIndex) targetIndex -= 1;
                final item = _items.removeAt(oldIndex);
                _items.insert(targetIndex, item);
              });
              _pushHistory();
              final id = _ensureCurrentId();
              final item = _items[targetIndex];
              final msg = "明細を並べ替えました: ${item.description} を ${oldIndex + 1} → ${targetIndex + 1}";
              await _editLogRepo.addLog(id, msg);
              await _loadEditLogs();
            },
            buildDefaultDragHandles: false,
            itemBuilder: (context, idx) {
              final item = _items[idx];
              return ReorderableDelayedDragStartListener(
                key: ValueKey('item_${idx}_${item.description}'),
                index: idx,
                child: Card(
                  margin: const EdgeInsets.only(bottom: 6),
                  elevation: 0.5,
                  child: ListTile(
                    dense: true,
                    contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
                    title: Text(item.description, style: const TextStyle(fontSize: 13.5)),
                    subtitle: Text("￥${fmt.format(item.unitPrice)} x ${item.quantity}", style: const TextStyle(fontSize: 12.5)),
                    trailing: Row(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        if (!_isViewMode && !_isLocked) ...[
                          IconButton(
                            icon: const Icon(Icons.remove, size: 18),
                            onPressed: () async {
                              if (item.quantity <= 1) return;
                              setState(() => _items[idx] = item.copyWith(quantity: item.quantity - 1));
                              _pushHistory();
                              final id = _ensureCurrentId();
                              final msg = "${item.description} の数量を ${item.quantity - 1} に変更しました";
                              await _editLogRepo.addLog(id, msg);
                              await _loadEditLogs();
                            },
                            constraints: const BoxConstraints.tightFor(width: 28, height: 28),
                            padding: EdgeInsets.zero,
                          ),
                          Text('${item.quantity}', style: const TextStyle(fontSize: 12.5)),
                          IconButton(
                            icon: const Icon(Icons.add, size: 18),
                            onPressed: () async {
                              setState(() => _items[idx] = item.copyWith(quantity: item.quantity + 1));
                              _pushHistory();
                              final id = _ensureCurrentId();
                              final msg = "${item.description} の数量を ${item.quantity + 1} に変更しました";
                              await _editLogRepo.addLog(id, msg);
                              await _loadEditLogs();
                            },
                            constraints: const BoxConstraints.tightFor(width: 28, height: 28),
                            padding: EdgeInsets.zero,
                          ),
                        ],
                        Text("￥${fmt.format(item.unitPrice * item.quantity)}", style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 13.5)),
                        const SizedBox(width: 6),
                        IconButton(
                          icon: const Icon(Icons.remove_circle_outline, color: Colors.redAccent, size: 18),
                          onPressed: () async {
                            final removed = _items[idx];
                            setState(() => _items.removeAt(idx));
                            _pushHistory();
                            final id = _ensureCurrentId();
                            final msg = "商品「${removed.description}」を削除しました";
                            await _editLogRepo.addLog(id, msg);
                            await _loadEditLogs();
                          },
                          tooltip: "削除",
                          constraints: const BoxConstraints.tightFor(width: 32, height: 32),
                          padding: EdgeInsets.zero,
                        ),
                      ],
                    ),
                    onTap: () async {
                      if (_isViewMode || _isLocked) return;
                      final messenger = ScaffoldMessenger.of(context);
                      final product = await Navigator.push<Product>(
                        context,
                        MaterialPageRoute(builder: (_) => const ProductMasterScreen(selectionMode: true)),
                      );
                      if (product != null) {
                        if (!mounted) return;
                        final prevDesc = item.description;
                        setState(() {
                          _items[idx] = item.copyWith(
                            productId: product.id,
                            description: product.name,
                            unitPrice: product.defaultUnitPrice,
                          );
                        });
                        _pushHistory();
                        final id = _ensureCurrentId();
                        final msg = "商品を $prevDesc から ${product.name} に変更しました";
                        await _editLogRepo.addLog(id, msg);
                        await _loadEditLogs();
                        if (!mounted) return;
                        messenger.showSnackBar(SnackBar(content: Text(msg)));
                      }
                    },
                  ),
                ),
              );
            },
          ),
      ],
    );
  }

  Widget _buildSummarySection(NumberFormat formatter) {
    final int subtotal = _subTotal;
    final int tax = _includeTax ? (subtotal * _taxRate).floor() : 0;
    final int total = subtotal + tax;

    final useBlue = _summaryIsBlue;
    final bgColor = useBlue ? Colors.indigo : Colors.white;
    final borderColor = Colors.transparent;
    final labelColor = useBlue ? Colors.white70 : Colors.black87;
    final totalColor = useBlue ? Colors.white : Colors.black87;
    final dividerColor = useBlue ? Colors.white24 : Colors.grey.shade300;

    return GestureDetector(
      onLongPress: () async {
        final selected = await showModalBottomSheet<String>(
          context: context,
          shape: const RoundedRectangleBorder(borderRadius: BorderRadius.vertical(top: Radius.circular(16))),
          builder: (context) => SafeArea(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                ListTile(
                  leading: const Icon(Icons.palette, color: Colors.indigo),
                  title: const Text('インディゴ'),
                  onTap: () => Navigator.pop(context, 'blue'),
                ),
                ListTile(
                  leading: const Icon(Icons.palette, color: Colors.grey),
                  title: const Text('白'),
                  onTap: () => Navigator.pop(context, 'white'),
                ),
              ],
            ),
          ),
        );
        if (selected == null) return;
        setState(() => _summaryIsBlue = selected == 'blue');
        await _settingsRepo.setSummaryTheme(selected);
      },
      child: Container(
        width: double.infinity,
        padding: const EdgeInsets.all(16),
        decoration: BoxDecoration(
          color: bgColor,
          borderRadius: BorderRadius.circular(12),
          border: Border.all(color: borderColor),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            _buildSummaryRow("小計", "￥${formatter.format(subtotal)}", labelColor),
            if (tax > 0) ...[
              Divider(color: dividerColor),
              _buildSummaryRow("消費税", "￥${formatter.format(tax)}", labelColor),
            ],
            Divider(color: dividerColor),
            _buildSummaryRow(
              tax > 0 ? "合計金額 (税込)" : "合計金額",
              "￥${formatter.format(total)}",
              totalColor,
              isTotal: true,
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildSummaryRow(String label, String value, Color textColor, {bool isTotal = false}) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 2),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Text(
            label,
            style: TextStyle(
              fontSize: isTotal ? 16 : 14,
              fontWeight: isTotal ? FontWeight.w600 : FontWeight.normal,
              color: textColor,
            ),
          ),
          Text(
            value,
            style: TextStyle(
              fontSize: isTotal ? 18 : 14,
              fontWeight: FontWeight.w600,
              color: isTotal ? Colors.white : textColor,
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildBottomActionBar() {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 20),
      decoration: BoxDecoration(
        color: Colors.white,
        boxShadow: [BoxShadow(color: Colors.black12, blurRadius: 10, offset: const Offset(0, -5))],
      ),
      child: SafeArea(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Row(
              children: [
                Expanded(
                  child: OutlinedButton.icon(
                    onPressed: _items.isEmpty ? null : _showPreview,
                    icon: const Icon(Icons.picture_as_pdf), // アイコン変更
                    label: const Text("PDFプレビュー"), // 名称変更
                    style: OutlinedButton.styleFrom(
                      padding: const EdgeInsets.symmetric(vertical: 16),
                      side: const BorderSide(color: Colors.indigo),
                    ),
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: _isLocked
                      ? ElevatedButton.icon(
                          onPressed: null,
                          icon: const Icon(Icons.lock),
                          label: const Text("ロック中"),
                        )
                      : (_isViewMode
                          ? ElevatedButton.icon(
                              onPressed: () => setState(() => _isViewMode = false),
                              icon: const Icon(Icons.edit),
                              label: const Text("編集"),
                              style: ElevatedButton.styleFrom(
                                backgroundColor: Colors.indigo,
                                foregroundColor: Colors.white,
                                padding: const EdgeInsets.symmetric(vertical: 16),
                              ),
                            )
                          : ElevatedButton.icon(
                              onPressed: () => _saveInvoice(generatePdf: false),
                              icon: const Icon(Icons.save),
                              label: const Text("保存"),
                              style: ElevatedButton.styleFrom(
                                backgroundColor: Colors.indigo,
                                foregroundColor: Colors.white,
                                padding: const EdgeInsets.symmetric(vertical: 16),
                              ),
                            )),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildSubjectSection(Color textColor) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text("案件名 / 件名", style: TextStyle(fontWeight: FontWeight.bold, color: textColor)),
        const SizedBox(height: 8),
        Container(
          width: double.infinity,
          padding: const EdgeInsets.all(12),
          decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.circular(12),
            boxShadow: [BoxShadow(color: Colors.black.withValues(alpha: 0.06), blurRadius: 8, offset: const Offset(0, 3))],
          ),
          child: TextField(
            focusNode: _subjectFocusNode,
            controller: _subjectController,
            style: TextStyle(color: textColor),
            readOnly: _isViewMode || _isLocked,
            enableInteractiveSelection: !(_isViewMode || _isLocked),
            decoration: InputDecoration(
              hintText: "例：事務所改修工事 / 〇〇月分リース料",
              hintStyle: TextStyle(color: textColor.withAlpha((0.5 * 255).round())),
              border: InputBorder.none,
              isDense: true,
              contentPadding: const EdgeInsets.symmetric(horizontal: 4, vertical: 4),
            ),
          ),
        ),
      ],
    );
  }

  Widget _buildEditLogsSection() {
    if (_currentId == null) {
      return const SizedBox.shrink();
    }
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Card(
          shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
          elevation: 0.5,
          child: Container(
            decoration: BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.circular(12),
              boxShadow: const [
                BoxShadow(
                  color: Color(0x22000000),
                  blurRadius: 10,
                  spreadRadius: -4,
                  offset: Offset(0, 2),
                  blurStyle: BlurStyle.inner,
                ),
              ],
            ),
            padding: const EdgeInsets.all(12),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const Text("編集ログ (直近1週間)", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 13)),
                const SizedBox(height: 8),
                if (_editLogs.isEmpty)
                  const Text("編集ログはありません", style: TextStyle(color: Colors.grey, fontSize: 12))
                else
                  ..._editLogs.map((e) => Padding(
                        padding: const EdgeInsets.symmetric(vertical: 4),
                        child: Row(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            const Icon(Icons.circle, size: 6, color: Colors.grey),
                            const SizedBox(width: 8),
                            Expanded(
                              child: Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Text(
                                    DateFormat('yyyy/MM/dd HH:mm').format(e.createdAt),
                                    style: const TextStyle(fontSize: 11, color: Colors.black54),
                                  ),
                                  Text(
                                    e.message,
                                    style: const TextStyle(fontSize: 13),
                                  ),
                                ],
                              ),
                            ),
                          ],
                        ),
                      )),
              ],
            ),
          ),
        ),
      ],
    );
  }
}

class _DraftBadge extends StatelessWidget {
  const _DraftBadge();

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
      decoration: BoxDecoration(
        color: Colors.orange.shade100,
        borderRadius: BorderRadius.circular(10),
      ),
      child: const Text(
        '下書き',
        style: TextStyle(fontSize: 11, fontWeight: FontWeight.w700, color: Colors.orange),
      ),
    );
  }
}

class _InvoiceSnapshot {
  final Customer? customer;
  final List<InvoiceItem> items;
  final double taxRate;
  final bool includeTax;
  final DocumentType documentType;
  final DateTime date;
  final bool isDraft;
  final String subject;

  _InvoiceSnapshot({
    required this.customer,
    required this.items,
    required this.taxRate,
    required this.includeTax,
    required this.documentType,
    required this.date,
    required this.isDraft,
    required this.subject,
  });
}
