import { Request, Response } from 'express';
import crypto from 'crypto';
import path from 'path';
import { Document } from '@models/Document';
import { User } from '@models/User';
import { ResponseHandler } from '@utils/responseHandler';
import { activityService } from '@services/activity.service';
import type { AuthenticatedRequest } from '../types/express';
import { getRequestMetadata } from '@utils/requestUtils';
import { getConfigNumber, getConfigValue } from '@services/configReader.service';

export class DocumentController {
  async upload(req: AuthenticatedRequest, res: Response): Promise<void> {
    try {
      const userId = req.user?.userId;
      if (!userId) {
        ResponseHandler.error(res, 'Unauthorized', 401);
        return;
      }

      const requestId = String((req.body?.requestId || '').trim());
      if (!requestId) {
        ResponseHandler.error(res, 'requestId is required', 400);
        return;
      }

      const file = (req as any).file as Express.Multer.File | undefined;
      if (!file) {
        ResponseHandler.error(res, 'No file uploaded', 400);
        return;
      }

      // Validate file size against database configuration
      const maxFileSizeMB = await getConfigNumber('MAX_FILE_SIZE_MB', 10);
      const maxFileSizeBytes = maxFileSizeMB * 1024 * 1024;
      
      if (file.size > maxFileSizeBytes) {
        ResponseHandler.error(
          res,
          `File size exceeds the maximum allowed size of ${maxFileSizeMB}MB. Current size: ${(file.size / (1024 * 1024)).toFixed(2)}MB`,
          400
        );
        return;
      }

      // Validate file type against database configuration
      const allowedFileTypesStr = await getConfigValue('ALLOWED_FILE_TYPES', 'pdf,doc,docx,xls,xlsx,ppt,pptx,jpg,jpeg,png,gif');
      const allowedFileTypes = allowedFileTypesStr.split(',').map(ext => ext.trim().toLowerCase());
      const fileExtension = path.extname(file.originalname).replace('.', '').toLowerCase();
      
      if (!allowedFileTypes.includes(fileExtension)) {
        ResponseHandler.error(
          res,
          `File type "${fileExtension}" is not allowed. Allowed types: ${allowedFileTypes.join(', ')}`,
          400
        );
        return;
      }

      const checksum = crypto.createHash('sha256').update(file.buffer || '').digest('hex');
      const extension = path.extname(file.originalname).replace('.', '').toLowerCase();
      const category = (req.body?.category as string) || 'OTHER';

      const doc = await Document.create({
        requestId,
        uploadedBy: userId,
        fileName: path.basename(file.filename || file.originalname),
        originalFileName: file.originalname,
        fileType: extension,
        fileExtension: extension,
        fileSize: file.size,
        filePath: file.path, // server path
        storageUrl: `/uploads/${path.basename(file.path)}`,
        mimeType: file.mimetype,
        checksum,
        isGoogleDoc: false,
        googleDocUrl: null as any,
        category,
        version: 1,
        parentDocumentId: null as any,
        isDeleted: false,
        downloadCount: 0,
      } as any);

      // Get user details for activity logging
      const user = await User.findByPk(userId);
      const uploaderName = (user as any)?.displayName || (user as any)?.email || 'User';
      
      // Log activity for document upload
      const requestMeta = getRequestMetadata(req);
      await activityService.log({
        requestId,
        type: 'document_added',
        user: { userId, name: uploaderName },
        timestamp: new Date().toISOString(),
        action: 'Document Added',
        details: `Added ${file.originalname} as supporting document by ${uploaderName}`,
        metadata: { 
          fileName: file.originalname, 
          fileSize: file.size, 
          fileType: extension,
          category 
        },
        ipAddress: requestMeta.ipAddress,
        userAgent: requestMeta.userAgent
      });

      ResponseHandler.success(res, doc, 'File uploaded', 201);
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Unknown error';
      ResponseHandler.error(res, 'Upload failed', 500, message);
    }
  }
}


