import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Bill } from '../entities/bill.entity';
import { BillItem } from '../entities/bill-item.entity';
import { Deposit } from '../entities/deposit.entity';
import * as ExcelJS from 'exceljs';
import * as PDFDocument from 'pdfkit';
import { Response } from 'express';

@Injectable()
export class BillsExportService {
  constructor(
    @InjectRepository(Bill) private billRepo: Repository<Bill>,
    @InjectRepository(BillItem) private itemRepo: Repository<BillItem>,
    @InjectRepository(Deposit) private depositRepo: Repository<Deposit>,
  ) {}

  /**
   * 导出账单列表为 Excel
   */
  async exportExcel(
    query: { periodStart?: string; periodEnd?: string; studentId?: number; status?: string },
    res: Response,
  ) {
    const qb = this.billRepo
      .createQueryBuilder('b')
      .leftJoinAndSelect('b.student', 'student')
      .leftJoinAndSelect('b.items', 'items')
      .orderBy('b.generatedAt', 'DESC');
    if (query.periodStart) qb.andWhere('b.periodStart = :ps', { ps: query.periodStart });
    if (query.periodEnd) qb.andWhere('b.periodEnd = :pe', { pe: query.periodEnd });
    if (query.studentId) qb.andWhere('b.studentId = :sid', { sid: query.studentId });
    if (query.status) qb.andWhere('b.status = :status', { status: query.status });
    const bills = await qb.getMany();

    const workbook = new ExcelJS.Workbook();
    workbook.creator = '学生管理系统';

    // Sheet 1: 账单汇总
    const ws = workbook.addWorksheet('账单汇总');
    ws.columns = [
      { header: '账单ID', key: 'id', width: 10 },
      { header: '学生姓名', key: 'studentName', width: 14 },
      { header: '计费周期', key: 'period', width: 24 },
      { header: '分摊费用', key: 'shared', width: 12 },
      { header: '个人费用', key: 'personal', width: 12 },
      { header: '总金额', key: 'total', width: 12 },
      { header: '已扣余额', key: 'paidAmount', width: 12 },
      { header: '待补缴', key: 'outstandingAmount', width: 12 },
      { header: '状态', key: 'status', width: 10 },
      { header: '生成时间', key: 'generatedAt', width: 20 },
    ];
    // 表头样式
    ws.getRow(1).font = { bold: true };
    ws.getRow(1).fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFE0E0E0' } };

    const statusMap: Record<string, string> = {
      unpaid: '待支付',
      partially_paid: '部分支付',
      paid: '已结清',
      cancelled: '已取消',
    };
    for (const bill of bills) {
      const total = Number(bill.totalAmount || 0);
      ws.addRow({
        id: bill.id,
        studentName: (bill as any).student?.name || '-',
        period: `${bill.periodStart} ~ ${bill.periodEnd}`,
        shared: Number(bill.sharedAmount),
        personal: Number(bill.personalAmount),
        total,
        paidAmount: Number(bill.paidAmount || 0),
        outstandingAmount: Number(bill.outstandingAmount || 0),
        status: statusMap[bill.status] || bill.status,
        generatedAt: bill.generatedAt ? new Date(bill.generatedAt).toLocaleString('zh-CN') : '',
      });
    }

    // Sheet 2: 费用明细
    const ws2 = workbook.addWorksheet('费用明细');
    ws2.columns = [
      { header: '账单ID', key: 'billId', width: 10 },
      { header: '学生姓名', key: 'studentName', width: 14 },
      { header: '费用类型', key: 'expenseType', width: 12 },
      { header: '说明', key: 'description', width: 24 },
      { header: '计费天数', key: 'days', width: 10 },
      { header: '宿舍总人天', key: 'totalRoomDays', width: 12 },
      { header: '宿舍总费用', key: 'roomTotal', width: 12 },
      { header: '学生应付', key: 'studentAmount', width: 12 },
    ];
    ws2.getRow(1).font = { bold: true };
    ws2.getRow(1).fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFE0E0E0' } };

    for (const bill of bills) {
      for (const item of bill.items || []) {
        ws2.addRow({
          billId: bill.id,
          studentName: (bill as any).student?.name || '-',
          expenseType: item.expenseType,
          description: item.description,
          days: item.days,
          totalRoomDays: item.totalRoomDays,
          roomTotal: Number(item.roomTotalAmount),
          studentAmount: Number(item.studentAmount),
        });
      }
    }

    res.setHeader(
      'Content-Type',
      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    );
    res.setHeader('Content-Disposition', `attachment; filename=bills_${Date.now()}.xlsx`);
    await workbook.xlsx.write(res);
    res.end();
  }

  /**
   * 导出单个学生的 PDF 账单
   */
  async exportStudentPdf(billId: number, res: Response) {
    const bill = await this.billRepo.findOne({
      where: { id: billId },
      relations: ['student', 'items'],
    });
    if (!bill) {
      res.status(404).json({ message: '账单不存在' });
      return;
    }

    const totalAmount = Number(bill.totalAmount || 0);
    const paidAmount = Number(bill.paidAmount || 0);
    const outstandingAmount = Number(bill.outstandingAmount || 0);

    const doc = new PDFDocument({ size: 'A4', margin: 50 });
    res.setHeader('Content-Type', 'application/pdf');
    res.setHeader('Content-Disposition', `attachment; filename=bill_${billId}.pdf`);
    doc.pipe(res);

    // 注册中文字体（优先使用系统字体，兼容 macOS 和 Linux）
    const fontPaths = [
      '/System/Library/Fonts/PingFang.ttc', // macOS
      '/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc', // Linux Noto
      '/usr/share/fonts/truetype/noto/NotoSansCJK-Regular.ttc',
      '/usr/share/fonts/google-noto-cjk/NotoSansCJK-Regular.ttc',
      '/usr/share/fonts/noto-cjk/NotoSansSC-Regular.otf',
      '/usr/share/fonts/wqy-microhei/wqy-microhei.ttc', // Linux WenQuanYi
      '/usr/share/fonts/truetype/wqy/wqy-microhei.ttc',
    ];
    let fontRegistered = false;
    const fs = require('fs');
    for (const fp of fontPaths) {
      try {
        if (fs.existsSync(fp)) {
          doc.registerFont('Chinese', fp);
          doc.font('Chinese');
          fontRegistered = true;
          break;
        }
      } catch {}
    }
    if (!fontRegistered) {
      // 如果没有中文字体，使用 Helvetica（中文可能乱码）
      doc.font('Helvetica');
    }

    const statusMap: Record<string, string> = {
      unpaid: '待支付',
      partially_paid: '部分支付',
      paid: '已结清',
      cancelled: '已取消',
    };

    // 标题
    doc.fontSize(20).text('恭学教育基地水电费账单', { align: 'center' });
    doc.moveDown(0.5);
    doc
      .fontSize(10)
      .fillColor('#666')
      .text(`生成时间: ${new Date().toLocaleString('zh-CN')}`, { align: 'center' });
    doc.moveDown(1);

    // 基本信息
    doc.fontSize(12).fillColor('#000');
    doc.text(`学生姓名: ${(bill as any).student?.name || '-'}`);
    doc.text(`计费周期: ${bill.periodStart} ~ ${bill.periodEnd}`);
    doc.text(`账单状态: ${statusMap[bill.status] || bill.status}`);
    doc.moveDown(0.5);

    // 金额汇总
    doc.fontSize(14).text('费用汇总', { underline: true });
    doc.moveDown(0.3);
    doc.fontSize(12);
    doc.text(`分摊费用: ¥${Number(bill.sharedAmount).toFixed(2)}`);
    doc.text(`个人费用: ¥${Number(bill.personalAmount).toFixed(2)}`);
    doc
      .fontSize(14)
      .fillColor('#007AFF')
      .text(`应付总额: ¥${totalAmount.toFixed(2)}`);
    doc.moveDown(0.3);
    doc.fontSize(11).fillColor('#389E0D').text(`已扣余额: ¥${paidAmount.toFixed(2)}`);
    doc.fontSize(14).fillColor(outstandingAmount > 0 ? '#FF3B30' : '#389E0D').text(`待补缴: ¥${outstandingAmount.toFixed(2)}`);
    doc.moveDown(1);

    // 明细表格
    doc.fontSize(14).fillColor('#000').text('费用明细', { underline: true });
    doc.moveDown(0.5);

    const items = bill.items || [];
    const tableTop = doc.y;
    const colWidths = [120, 180, 60, 60, 70];
    const headers = ['费用类型', '说明', '天数', '总人天', '金额(元)'];

    // 表头
    doc.fontSize(10).fillColor('#333');
    let x = 50;
    for (let i = 0; i < headers.length; i++) {
      doc.text(headers[i], x, tableTop, { width: colWidths[i], align: 'left' });
      x += colWidths[i];
    }
    doc.moveDown(0.3);
    doc.moveTo(50, doc.y).lineTo(540, doc.y).stroke('#ccc');
    doc.moveDown(0.2);

    // 数据行
    for (const item of items) {
      const y = doc.y;
      x = 50;
      doc.fontSize(9).fillColor('#000');
      doc.text(item.expenseType || '', x, y, { width: colWidths[0] });
      x += colWidths[0];
      doc.text(item.description || '', x, y, { width: colWidths[1] });
      x += colWidths[1];
      doc.text(String(item.days || 0), x, y, { width: colWidths[2] });
      x += colWidths[2];
      doc.text(String(item.totalRoomDays || 0), x, y, { width: colWidths[3] });
      x += colWidths[3];
      doc.text(Number(item.studentAmount).toFixed(2), x, y, { width: colWidths[4] });
      doc.moveDown(0.8);
    }

    doc.moveDown(2);
    doc
      .fontSize(8)
      .fillColor('#999')
      .text('本账单由学生管理系统自动生成', { align: 'center' });

    doc.end();
  }
}
