import { Request, Response } from 'express';
import { prisma } from '../models';
import { Prisma, Role } from '@prisma/client';
import { writeAudit } from '../lib/audit';
import { NIDAAPIService } from '../services/nida-api.service';
import { bodyOtp } from '../lib/md-otp';

export const jvPartnerController = {
  async list(req: Request, res: Response) {
    const { id: licenseId } = req.params;
    const partners = await prisma.jVPartner.findMany({ where: { license_id: licenseId } });
    res.json({ success: true, data: { jv_partners: partners } });
  },

  async create(req: Request, res: Response) {
    const { id: licenseId } = req.params;
    const b = req.body as Record<string, unknown>;
    const full_name = String(b.full_name ?? '');
    const nida_number = String(b.nida_number ?? '');

    const nida = await NIDAAPIService.verifyIdentity(nida_number, full_name);
    if (!nida.verified) {
      res.status(400).json({ success: false, error: nida.error ?? 'NIDA verification failed' });
      return;
    }

    const partner = await prisma.jVPartner.create({
      data: {
        license_id: licenseId,
        full_name,
        nida_number,
        date_of_birth: new Date(String(b.date_of_birth)),
        nationality: String(b.nationality ?? ''),
        gender: String(b.gender ?? ''),
        phone: String(b.phone ?? ''),
        email: b.email ? String(b.email) : null,
        equity_percentage: Number(b.equity_percentage),
        role_in_jv: String(b.role_in_jv ?? ''),
        contract_start_date: new Date(String(b.contract_start_date)),
        contract_end_date: new Date(String(b.contract_end_date)),
        contract_pdf_url: String(b.contract_pdf_url ?? ''),
        nida_verified: true,
        nida_verification_date: new Date(),
        nida_face_match_percent: nida.face_match_percentage ?? null,
      },
    });

    await writeAudit(req, 'CREATE', 'JVPartner', partner.id, undefined, partner as unknown as Prisma.JsonValue);
    res.status(201).json({ success: true, data: partner });
  },

  async update(req: Request, res: Response) {
    const { id } = req.params;
    const existing = await prisma.jVPartner.findUnique({ where: { id } });
    if (!existing) {
      res.status(404).json({ success: false, error: 'Not found' });
      return;
    }

    const b = req.body as Record<string, unknown>;
    if (existing.equity_locked && b.equity_percentage != null) {
      if (req.user!.role !== Role.MD) {
        res.status(403).json({ success: false, error: 'Equity locked; MD with OTP required' });
        return;
      }
      const otp = bodyOtp(req);
      if (otp !== process.env.MD_OTP) {
        res.status(403).json({ success: false, error: 'Invalid MD OTP for equity change' });
        return;
      }
    }

    const data: Prisma.JVPartnerUpdateInput = {};
    if (b.full_name != null) data.full_name = String(b.full_name);
    if (b.phone != null) data.phone = String(b.phone);
    if (b.email != null) data.email = String(b.email);
    if (b.equity_percentage != null) data.equity_percentage = Number(b.equity_percentage);
    if (b.role_in_jv != null) data.role_in_jv = String(b.role_in_jv);
    if (b.contract_end_date != null) data.contract_end_date = new Date(String(b.contract_end_date));

    const updated = await prisma.jVPartner.update({ where: { id }, data });
    await writeAudit(req, 'UPDATE', 'JVPartner', id, existing as unknown as Prisma.JsonValue, updated as unknown as Prisma.JsonValue);
    res.json({ success: true, data: updated });
  },

  async remove(req: Request, res: Response) {
    const { id } = req.params;
    await prisma.jVPartner.delete({ where: { id } });
    await writeAudit(req, 'DELETE', 'JVPartner', id);
    res.json({ success: true, message: 'Removed' });
  },

  async verifyNida(req: Request, res: Response) {
    const { id } = req.params;
    const p = await prisma.jVPartner.findUnique({ where: { id } });
    if (!p) {
      res.status(404).json({ success: false, error: 'Not found' });
      return;
    }
    const r = await NIDAAPIService.verifyIdentity(p.nida_number, p.full_name);
    if (!r.verified) {
      res.status(400).json({ success: false, error: r.error });
      return;
    }
    const updated = await prisma.jVPartner.update({
      where: { id },
      data: {
        nida_verified: true,
        nida_verification_date: new Date(),
        nida_face_match_percent: r.face_match_percentage ?? null,
      },
    });
    await writeAudit(req, 'VERIFY', 'JVPartner', id);
    res.json({ success: true, data: updated });
  },

  async lockEquity(req: Request, res: Response) {
    const { id } = req.params;
    const updated = await prisma.jVPartner.update({
      where: { id },
      data: { equity_locked: true },
    });
    await writeAudit(req, 'UPDATE', 'JVPartner', id);
    res.json({ success: true, data: updated });
  },

  async unlockEquityRequest(req: Request, res: Response) {
    const { id } = req.params;
    const reason = String((req.body as { reason?: string }).reason ?? '');
    const updated = await prisma.jVPartner.update({
      where: { id },
      data: { equity_unlock_request_reason: reason },
    });
    await writeAudit(req, 'UPDATE', 'JVPartner', id);
    res.json({ success: true, data: updated });
  },
};
