import 'dart:io';

import 'package:excel/excel.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';

/// Excel 模板服务
///
/// 生成 .xlsx 模板用于程序/步骤批量导入。
/// 模板包含两张表：
///   - Programs：程序基础信息
///   - Steps：步骤参数（通过 program_code 与 Programs 关联）
class ExcelTemplateService {
  static final ExcelTemplateService instance = ExcelTemplateService._internal();

  ExcelTemplateService._internal();

  /// 工作表名称
  static const String sheetPrograms = 'Programs';
  static const String sheetSteps = 'Steps';

  /// 模板文件名
  static const String templateFilename = 'program_template.xlsx';

  /// Android 端写入公共 Downloads 的 MethodChannel（对应 MainActivity.kt）
  static const MethodChannel _downloadsChannel =
      MethodChannel('com.xiarui.kuaishai2/downloads');

  /// 生成模板并保存到下载目录，返回可显示的路径字符串
  ///
  /// - Android：通过 MediaStore 写入公共 Downloads (`/storage/emulated/0/Download/`)
  /// - 其它平台：使用 [getDownloadsDirectory]，不可用时回退到应用文档目录
  Future<String> generateTemplate() async {
    final excel = Excel.createExcel();
    final bytes = _buildTemplateBytes(excel);

    if (Platform.isAndroid) {
      final saved = await _downloadsChannel.invokeMethod<String>(
        'saveToDownloads',
        <String, dynamic>{
          'filename': templateFilename,
          'bytes': bytes,
        },
      );
      if (saved == null) {
        throw StateError('保存到 Downloads 失败：未返回路径');
      }
      return saved;
    }

    final dir =
        await getDownloadsDirectory() ?? await getApplicationDocumentsDirectory();
    final file = File('${dir.path}/$templateFilename');
    await file.writeAsBytes(bytes, flush: true);
    return file.path;
  }

  /// 构建模板字节流（可在测试中直接调用）
  List<int> _buildTemplateBytes(Excel excel) {
    // 默认创建的第一个 sheet 重命名
    final defaultSheet = excel.getDefaultSheet();
    if (defaultSheet != null && defaultSheet != sheetPrograms) {
      excel.rename(defaultSheet, sheetPrograms);
    }

    _writeProgramsSheet(excel);
    _writeStepsSheet(excel);
    return excel.encode()!;
  }

  void _writeProgramsSheet(Excel excel) {
    final sheet = excel[sheetPrograms];
    final headerStyle = CellStyle(
      bold: true,
      backgroundColorHex: ExcelColor.fromHexString('FFD9E1F2'),
      horizontalAlign: HorizontalAlign.Center,
    );

    // 表头
    final headers = ['code', 'name', 'temperature', 'airflowTime', 'status'];
    sheet.appendRow(headers.map((h) => TextCellValue(h)).toList());
    for (var i = 0; i < headers.length; i++) {
      sheet
          .cell(CellIndex.indexByColumnRow(columnIndex: i, rowIndex: 0))
          .cellStyle = headerStyle;
    }

    // 示例行
    final sample1 = ['P001', '示例程序-标准流程', 50, 60, 1];
    final sample2 = ['P002', '示例程序-快速流程', 45, 30, 1];
    sheet.appendRow(sample1.map((v) => TextCellValue(v.toString())).toList());
    sheet.appendRow(sample2.map((v) => TextCellValue(v.toString())).toList());

    // 说明行（用前缀标记，避免被解析）
    final note = '说明：code 必填且唯一；name 必填；temperature/airflowTime 整数；status:1启用 0停用';
    sheet.appendRow([TextCellValue(note)]);

    // 列宽
    sheet.setColumnWidth(0, 14);
    sheet.setColumnWidth(1, 26);
    sheet.setColumnWidth(2, 14);
    sheet.setColumnWidth(3, 14);
    sheet.setColumnWidth(4, 10);
  }

  void _writeStepsSheet(Excel excel) {
    final sheet = excel[sheetSteps];
    final headerStyle = CellStyle(
      bold: true,
      backgroundColorHex: ExcelColor.fromHexString('FFD9E1F2'),
      horizontalAlign: HorizontalAlign.Center,
    );

    final headers = [
      'program_code',
      'step_no',
      'position',
      'name',
      'mixTime',
      'magnetTime',
      'volume',
      'blowTime',
      'speed',
    ];
    sheet.appendRow(headers.map((h) => TextCellValue(h)).toList());
    for (var i = 0; i < headers.length; i++) {
      sheet
          .cell(CellIndex.indexByColumnRow(columnIndex: i, rowIndex: 0))
          .cellStyle = headerStyle;
    }

    // 示例行：P001 / P002 各两步
    final samples = <List<Object>>[
      ['P001', 1, 'A1', '加样', 30, 0, 500, 0, 5],
      ['P001', 2, 'A2', '混合', 60, 10, 300, 30, 5],
      ['P002', 1, 'B1', '混合', 20, 5, 400, 0, 4],
    ];
    for (final row in samples) {
      sheet.appendRow(row.map((v) {
        if (v is num) return IntCellValue(v.toInt());
        return TextCellValue(v.toString());
      }).toList());
    }

    // 说明行
    final note =
        '说明：program_code 对应 Programs.code；step_no 整数从 1 开始；position 形如 A1/B2；mixTime/magnetTime/volume/blowTime 单位秒或微升；speed 1-10';
    sheet.appendRow([TextCellValue(note)]);

    // 列宽
    sheet.setColumnWidth(0, 14);
    sheet.setColumnWidth(1, 10);
    sheet.setColumnWidth(2, 12);
    sheet.setColumnWidth(3, 14);
    sheet.setColumnWidth(4, 10);
    sheet.setColumnWidth(5, 12);
    sheet.setColumnWidth(6, 10);
    sheet.setColumnWidth(7, 10);
    sheet.setColumnWidth(8, 8);
  }
}
