import prisma from "../utils/db";
import { DocumentType } from "@prisma/client";

export class LegalService {
  public async createDocument(data: {
    type: DocumentType;
    version: string;
    content: string;
    pdfUrl?: string | null;
  }) {
    // Deprecate older active versions of the same type
    if (data.type) {
      await prisma.legalDocument.updateMany({
        where: { type: data.type, isActive: true },
        data: { isActive: false },
      });
    }

    return await prisma.legalDocument.create({
      data: { ...data, isActive: true },
    });
  }

  public async getActiveDocument(type: DocumentType, userId?: string) {
    if (userId) {
      const user = await prisma.user.findUnique({
        where: { id: userId },
        select: { assignedNdaId: true, assignedMsaId: true }
      });
      if (user) {
        const assignedId = type === 'NDA' ? user.assignedNdaId : user.assignedMsaId;
        if (assignedId) {
          const doc = await prisma.legalDocument.findUnique({
            where: { id: assignedId }
          });
          if (doc) return doc;
        } else {
          return null;
        }
      }
    }

    return await prisma.legalDocument.findFirst({
      where: { type, isActive: true },
    });
  }

  public async recordAcceptance(
    docId: string,
    userId: string,
    ipAddress: string,
    signatureHash?: string,
    documentUrl?: string,
    signatureBase64?: string,
  ) {
    // Record acceptance
    const acceptance = await prisma.legalAcceptance.create({
      data: { docId, userId, ipAddress, signatureHash, documentUrl, signatureBase64 },
    });

    return acceptance;
  }

  public async checkOnboardingCompletion(userId: string) {
    const user = await prisma.user.findUnique({
      where: { id: userId },
      select: { assignedNdaId: true, assignedMsaId: true }
    });

    const acceptances = await prisma.legalAcceptance.findMany({
      where: { userId },
      include: { document: true }
    });

    const hasNDA = !user?.assignedNdaId || acceptances.some(a => a.document.type === 'NDA');
    const hasMSA = !user?.assignedMsaId || acceptances.some(a => a.document.type === 'MSA');

    if (hasNDA && hasMSA) {
      // Both signed or skipped, ready for admin approval. We don't automatically set to APPROVED.
      // But we can ensure it's PENDING_APPROVAL.
      await prisma.user.update({
        where: { id: userId },
        data: { onboardingStatus: 'PENDING_APPROVAL' }
      });
    }
    
    return { hasNDA, hasMSA };
  }

  public async getAcceptances(userId: string) {
    return await prisma.legalAcceptance.findMany({
      where: { userId },
      select: {
        id: true,
        signatureHash: true,
        documentUrl: true,
        signatureBase64: true,
        ipAddress: true,
        acceptedAt: true,
        document: true,
      },
    });
  }

  public async getPendingApprovals() {
    return await prisma.user.findMany({
      where: { onboardingStatus: 'PENDING_APPROVAL' },
      select: {
        id: true,
        email: true,
        createdAt: true,
        assignedNdaId: true,
        assignedMsaId: true,
        acceptances: {
          select: {
            id: true,
            signatureHash: true,
            documentUrl: true,
            signatureBase64: true,
            ipAddress: true,
            acceptedAt: true,
            document: true,
          }
        }
      }
    });
  }

  public async getAllDocuments() {
    return await prisma.legalDocument.findMany({
      orderBy: { createdAt: 'desc' }
    });
  }

  public async approvePartner(userId: string) {
    return await prisma.user.update({
      where: { id: userId },
      data: { onboardingStatus: 'APPROVED' }
    });
  }
}
