const router = require('express').Router();
const prisma  = require('../config/db');
const { writeAuditLog } = require('../middleware/audit');

// FlashToken 포함 조회 헬퍼
async function findToken(token) {
  return prisma.flashToken.findUnique({
    where: { token },
    include: {
      order: {
        include: {
          product: {
            include: {
              project: {
                select: {
                  id: true, title: true, chipFamily: true,
                  files: {
                    where: { fileType: 'firmware' },
                    orderBy: { displayOrder: 'asc' },
                  },
                },
              },
            },
          },
        },
      },
    },
  });
}

// GET /api/flash/:token — 토큰 유효성 확인 (Flash 페이지, webflash 둘 다 사용)
router.get('/:token', async (req, res) => {
  try {
    const ft = await findToken(req.params.token);
    if (!ft) return res.status(404).json({ error: '유효하지 않은 토큰입니다' });

    const expired = new Date() > new Date(ft.expiresAt);
    const project = ft.order.product.project;

    res.json({
      valid:       !expired && !ft.isUsed,
      isUsed:      ft.isUsed,
      expired,
      expiresAt:   ft.expiresAt,
      productName: project.title,
      chipFamily:  project.chipFamily,
      hasFirmware: project.files.length > 0,
      usedAt:      ft.usedAt,
    });
  } catch (err) {
    console.error(err);
    res.status(500).json({ error: '서버 오류' });
  }
});

// GET /api/flash/:token/manifest — esp-web-tools 매니페스트 반환
// 브라우저에서 직접 fetch하므로 CORS 허용
router.get('/:token/manifest', async (req, res) => {
  try {
    const ft = await findToken(req.params.token);
    if (!ft) return res.status(404).json({ error: '유효하지 않은 토큰입니다' });

    if (ft.isUsed) {
      return res.status(410).json({ error: '이미 플래시에 사용된 토큰입니다' });
    }
    if (new Date() > new Date(ft.expiresAt)) {
      return res.status(410).json({ error: '만료된 토큰입니다' });
    }

    const project = ft.order.product.project;
    if (!project.files.length) {
      return res.status(404).json({ error: '펌웨어 파일이 없습니다. 판매자에게 문의하세요.' });
    }

    const manifest = {
      name:                     project.title,
      new_install_improv_wait_ms: 0,
      builds: [{
        chipFamily: project.chipFamily,
        parts: project.files.map(f => ({
          path:   f.url,
          offset: parseInt(f.flashOffset || '0x0', 16),
        })),
      }],
    };

    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Content-Type', 'application/json');
    res.json(manifest);
  } catch (err) {
    console.error(err);
    res.status(500).json({ error: '서버 오류' });
  }
});

// POST /api/flash/:token/consume — 플래시 완료 기록
// esp-web-tools 또는 플래시 페이지에서 호출
router.post('/:token/consume', async (req, res) => {
  try {
    const ft = await findToken(req.params.token);
    if (!ft) return res.status(404).json({ error: '유효하지 않은 토큰입니다' });
    if (ft.isUsed)              return res.status(410).json({ error: '이미 사용된 토큰입니다' });
    if (new Date() > new Date(ft.expiresAt)) return res.status(410).json({ error: '만료된 토큰입니다' });

    const { mac = 'unknown', chipFamily, success = true, errorMessage } = req.body;
    const project = ft.order.product.project;

    await prisma.$transaction([
      prisma.flashToken.update({
        where: { id: ft.id },
        data: { isUsed: true, usedAt: new Date(), macAddress: mac, chipFamily: chipFamily || project.chipFamily },
      }),
      prisma.flashLog.create({
        data: {
          flashTokenId: ft.id,
          macAddress:   mac,
          chipFamily:   chipFamily || project.chipFamily,
          firmwareName: project.title,
          firmwareId:   project.id,
          success:      Boolean(success),
          errorMessage: errorMessage || null,
          clientIp:     req.ip || 'unknown',
          userAgent:    req.headers['user-agent'] || null,
        },
      }),
    ]);

    await writeAuditLog({
      userId: ft.order.buyerId,
      action: success ? 'FLASH_SUCCESS' : 'FLASH_FAIL',
      targetType: 'FlashToken', targetId: ft.id,
      req, metadata: { mac, chipFamily, firmwareId: project.id }, responseStatus: 200,
    });

    res.json({ success: true, message: success ? '플래시 완료 기록됨' : '실패 기록됨' });
  } catch (err) {
    console.error(err);
    res.status(500).json({ error: '서버 오류' });
  }
});

module.exports = router;
