import { Request, Response } from 'express';
import { prisma } from '../models';
import { DocumentType, Prisma, Role } from '@prisma/client';
import { CloudStorageService } from '../services/cloud-storage.service';
import { writeAudit } from '../lib/audit';

export const documentController = {
  async list(req: Request, res: Response) {
    const { id: licenseId } = req.params;
    const docs = await prisma.document.findMany({
      where: { license_id: licenseId, deleted_at: null },
      orderBy: { uploaded_at: 'desc' },
    });
    res.json({ success: true, data: { documents: docs } });
  },

  async upload(req: Request, res: Response) {
    const { id: licenseId } = req.params;
    const file = (req as Request & { file?: Express.Multer.File }).file;
    if (!file) {
      res.status(400).json({ success: false, error: 'File required' });
      return;
    }

    const body = req.body as {
      document_type: DocumentType;
      description?: string;
      expiry_date?: string;
      issued_by?: string;
      reference_number?: string;
      is_required?: string;
    };

    const url = await CloudStorageService.upload(
      file.buffer,
      `licenses/${licenseId}/${body.document_type}_${file.originalname}`,
      file.mimetype
    );

    const doc = await prisma.document.create({
      data: {
        license_id: licenseId,
        document_type: body.document_type,
        file_name: file.originalname,
        file_url: url,
        file_size: file.size,
        mime_type: file.mimetype,
        description: body.description,
        expiry_date: body.expiry_date ? new Date(body.expiry_date) : undefined,
        issued_by: body.issued_by,
        reference_number: body.reference_number,
        uploaded_by: req.user!.id,
        is_required: body.is_required === 'true',
      },
    });

    await writeAudit(req, 'CREATE', 'Document', doc.id, undefined, doc as unknown as Prisma.JsonValue);
    res.status(201).json({ success: true, data: doc });
  },

  async download(req: Request, res: Response) {
    const { id } = req.params;
    const doc = await prisma.document.findFirst({ where: { id, deleted_at: null } });
    if (!doc) {
      res.status(404).json({ success: false, error: 'Not found' });
      return;
    }
    const signed = await CloudStorageService.getSignedDownloadUrl(doc.file_url);
    res.json({ success: true, data: { url: signed } });
  },

  async softDelete(req: Request, res: Response) {
    const { id } = req.params;
    const doc = await prisma.document.findUnique({ where: { id } });
    if (!doc) {
      res.status(404).json({ success: false, error: 'Not found' });
      return;
    }
    const archivedKey = `archive/${id}_${doc.file_name}`;
    await CloudStorageService.archiveObject(doc.file_url, archivedKey);
    await prisma.document.update({
      where: { id },
      data: { deleted_at: new Date(), archived_key: archivedKey },
    });
    await writeAudit(req, 'DELETE', 'Document', id);
    res.json({ success: true, message: 'Document archived' });
  },

  async verify(req: Request, res: Response) {
    if (req.user!.role !== Role.LEGAL_OFFICER) {
      res.status(403).json({ success: false, error: 'Legal Officer only' });
      return;
    }
    const { id } = req.params;
    const updated = await prisma.document.update({
      where: { id },
      data: {
        verified: true,
        verified_by: req.user!.id,
        verified_at: new Date(),
      },
    });
    await writeAudit(req, 'VERIFY', 'Document', id);
    res.json({ success: true, data: updated });
  },
};
