// lib/services/pdf_generator.dart
// Version: 1.0.1
// Updated: 2026-02-08
// Description: 日本語対応PDF生成および命名規則に基づいたファイル保存

import 'dart:io';
import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:intl/intl.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
import 'package:path_provider/path_provider.dart';
import 'package:crypto/crypto.dart';
import '../models/invoice_models.dart';

class PdfGenerator {
  /// 請求書PDFを生成し、一意のファイル名で保存する
  static Future<File> generateInvoicePdf(Invoice invoice) async {
    final pdf = pw.Document();

    // 1. フォントの読み込み
    final fontData = await rootBundle.load("assets/fonts/ipaexg.ttf");
    final ttf = pw.Font.ttf(fontData);

    // 2. PDFコンテンツの構築
    pdf.addPage(
      pw.MultiPage(
        theme: pw.ThemeData.withFont(base: ttf),
        build: (pw.Context context) {
          return [
            pw.Header(
              level: 0,
              child: pw.Text("請求書", style: pw.TextStyle(fontSize: 24)),
            ),
            pw.SizedBox(height: 20),
            pw.Text("請求先: ${invoice.customer.formalName} 御中"),
            pw.Text("請求番号: ${invoice.invoiceNumber}"),
            pw.Text("日付: ${DateFormat('yyyy/MM/dd').format(invoice.date)}"),
            pw.Divider(),
            pw.Table.fromTextArray(
              headers: ['内容', '数量', '単価', '金額'],
              data: invoice.items.map((item) {
                return [
                  item.description,
                  item.quantity.toString(),
                  "¥${item.unitPrice}",
                  "¥${item.subtotal}",
                ];
              }).toList(),
            ),
            pw.SizedBox(height: 20),
            pw.Container(
              alignment: pw.Alignment.centerRight,
              child: pw.Column(
                crossAxisAlignment: pw.CrossAxisAlignment.end,
                children: [
                  pw.Text("小計: ¥${invoice.subtotal}"),
                  pw.Text("消費税: ¥${invoice.tax}"),
                  pw.Text("合計金額: ¥${invoice.totalAmount}",
                      style: pw.TextStyle(fontWeight: pw.FontWeight.bold)),
                ],
              ),
            ),
            if (invoice.notes != null) ...[
              pw.SizedBox(height: 20),
              pw.Text("備考:"),
              pw.Text(invoice.notes!),
            ],
          ];
        },
      ),
    );

    // 3. 命名規則に基づくファイル名の生成
    // 規則: [日付]_[依頼種別]_[顧客名]_[タイトル]_[金額]_[SHA256ハッシュ].pdf
    final dateStr = DateFormat('yyyyMMdd').format(invoice.date);
    
    // モデルにない項目は安全な代替値を使用
    const typeStr = "請求書"; // 固定またはInvoiceにプロパティ追加検討
    final customerStr = invoice.customer.formalName.replaceAll(RegExp(r'[\\/:*?"<>|]'), '');
    final titleStr = (invoice.notes != null && invoice.notes!.length > 10) 
        ? invoice.notes!.substring(0, 10) 
        : (invoice.items.isNotEmpty ? invoice.items.first.description : "名称未設定");
    final amountStr = invoice.totalAmount.toString();

    // SHA256ハッシュの生成
    final rawData = "$dateStr$customerStr$amountStr${invoice.invoiceNumber}";
    final hash = sha256.convert(utf8.encode(rawData)).toString().substring(0, 8);

    final fileName = "${dateStr}_${typeStr}_${customerStr}_${titleStr}_${amountStr}_$hash.pdf";

    // 4. 保存
    final directory = await getApplicationDocumentsDirectory();
    final file = File("${directory.path}/$fileName");
    await file.writeAsBytes(await pdf.save());

    return file;
  }
}