import type { Request, Response, NextFunction } from 'express';
import { AppError } from '../middlewares/error.middleware.js';
import * as fielService from '../services/contribuyente-fiel.service.js';
import * as facturapiService from '../services/contribuyente-facturapi.service.js';
import { getContribuyenteById } from '../services/contribuyente.service.js';

// ========== FIEL ==========

export async function uploadFiel(req: Request, res: Response, next: NextFunction) {
  try {
    const { cerFile, keyFile, password } = req.body;
    if (!cerFile || !keyFile || !password) {
      return next(new AppError(400, 'cerFile, keyFile y password son requeridos'));
    }
    const contribuyenteId = String(req.params.id);
    const contrib = await getContribuyenteById(req.tenantPool!, contribuyenteId);
    if (!contrib) return next(new AppError(404, 'Contribuyente no encontrado'));

    const result = await fielService.uploadFielContribuyente(req.tenantPool!, contribuyenteId, cerFile, keyFile, password);
    if (!result.success) {
      console.error('[FIEL Upload] Failed:', result.message);
      return res.status(400).json({ message: result.message });
    }
    return res.json(result);
  } catch (err: any) {
    console.error('[FIEL Upload] Exception:', err.message || err);
    return next(err);
  }
}

export async function fielStatus(req: Request, res: Response, next: NextFunction) {
  try {
    const contribuyenteId = String(req.params.id);
    const status = await fielService.getFielStatusContribuyente(req.tenantPool!, contribuyenteId);
    return res.json(status);
  } catch (err) { return next(err); }
}

export async function deleteFiel(req: Request, res: Response, next: NextFunction) {
  try {
    const contribuyenteId = String(req.params.id);
    // Delete from per-contribuyente table (tenant BD)
    await req.tenantPool!.query(
      'UPDATE fiel_contribuyente SET is_active = false WHERE contribuyente_id = $1',
      [contribuyenteId]
    );
    // Also try to deactivate legacy FIEL if it matches this contribuyente's RFC
    const { rows } = await req.tenantPool!.query('SELECT rfc FROM contribuyentes WHERE entidad_id = $1', [contribuyenteId]);
    if (rows[0]?.rfc) {
      const { prisma } = await import('../config/database.js');
      await prisma.fielCredential.updateMany({
        where: { rfc: rows[0].rfc },
        data: { isActive: false },
      }).catch(() => {});
    }
    return res.json({ message: 'FIEL eliminada' });
  } catch (err) { return next(err); }
}

// ========== FACTURAPI ==========

export async function createOrg(req: Request, res: Response, next: NextFunction) {
  try {
    const contribuyenteId = String(req.params.id);
    const contrib = await getContribuyenteById(req.tenantPool!, contribuyenteId);
    if (!contrib) return next(new AppError(404, 'Contribuyente no encontrado'));

    const result = await facturapiService.createOrgContribuyente(req.tenantPool!, contribuyenteId, contrib.nombre);
    return res.status(201).json(result);
  } catch (err: any) {
    if (err.message?.includes('ya tiene')) return next(new AppError(409, err.message));
    return next(err);
  }
}

export async function orgStatus(req: Request, res: Response, next: NextFunction) {
  try {
    const contribuyenteId = String(req.params.id);
    const status = await facturapiService.getOrgStatusContribuyente(req.tenantPool!, contribuyenteId);
    return res.json(status);
  } catch (err) { return next(err); }
}

export async function uploadCsd(req: Request, res: Response, next: NextFunction) {
  try {
    const { cerFile, keyFile, password } = req.body;
    if (!cerFile || !keyFile || !password) {
      return next(new AppError(400, 'cerFile, keyFile y password son requeridos'));
    }
    const contribuyenteId = String(req.params.id);
    const result = await facturapiService.uploadCsdContribuyente(req.tenantPool!, contribuyenteId, cerFile, keyFile, password);
    if (!result.success) return res.status(400).json({ message: result.message });
    return res.json(result);
  } catch (err) { return next(err); }
}
