import { WorkflowRequest } from '@models/WorkflowRequest';
import { Op } from 'sequelize';
import logger from './logger';

/**
 * Generate request number in format: REQ-YYYY-MM-XXXX
 * Counter resets every month
 * Example: REQ-2025-11-0001
 */
export const generateRequestNumber = async (): Promise<string> => {
  const now = new Date();
  const year = now.getFullYear();
  const month = (now.getMonth() + 1).toString().padStart(2, '0'); // Month is 0-indexed, so add 1
  
  // Build the prefix pattern for current year-month
  const prefix = `REQ-${year}-${month}-`;
  
  try {
    // Find the highest counter for the current year-month
    const existingRequests = await WorkflowRequest.findAll({
      where: {
        requestNumber: {
          [Op.like]: `${prefix}%`
        }
      },
      attributes: ['requestNumber'],
      order: [['requestNumber', 'DESC']],
      limit: 1
    });
    
    let counter = 1;
    
    if (existingRequests.length > 0) {
      // Extract the counter from the last request number
      const lastRequestNumber = (existingRequests[0] as any).requestNumber;
      const lastCounter = parseInt(lastRequestNumber.replace(prefix, ''), 10);
      
      if (!isNaN(lastCounter)) {
        counter = lastCounter + 1;
      }
    }
    
    // Format counter as 4-digit number (0001, 0002, etc.)
    const counterStr = counter.toString().padStart(4, '0');
    
    return `${prefix}${counterStr}`;
  } catch (error) {
    // Fallback to timestamp-based counter if database query fails
    logger.error('Error generating request number:', error);
    const fallbackCounter = Date.now().toString().slice(-4);
    return `${prefix}${fallbackCounter}`;
  }
};

export const calculateTATDays = (tatHours: number): number => {
  return Math.ceil(tatHours / 24);
};

export const calculateElapsedHours = (startTime: Date, endTime?: Date): number => {
  const end = endTime || new Date();
  const diffMs = end.getTime() - startTime.getTime();
  return Math.round((diffMs / (1000 * 60 * 60)) * 100) / 100; // Round to 2 decimal places
};

export const calculateTATPercentage = (elapsedHours: number, totalTatHours: number): number => {
  if (totalTatHours === 0) return 0;
  return Math.min(Math.round((elapsedHours / totalTatHours) * 100), 100);
};

export const isTATBreached = (elapsedHours: number, totalTatHours: number): boolean => {
  return elapsedHours > totalTatHours;
};

export const isTATApproaching = (elapsedHours: number, totalTatHours: number, threshold: number = 80): boolean => {
  const percentage = calculateTATPercentage(elapsedHours, totalTatHours);
  return percentage >= threshold && percentage < 100;
};

export const formatDate = (date: Date): string => {
  return date.toISOString().split('T')[0];
};

export const formatDateTime = (date: Date): string => {
  return date.toISOString();
};

export const isValidEmail = (email: string): boolean => {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return emailRegex.test(email);
};

export const isValidUUID = (uuid: string): boolean => {
  const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
  return uuidRegex.test(uuid);
};

export const sanitizeString = (str: string): string => {
  return str.trim().replace(/[<>]/g, '');
};

export const generateChecksum = (data: string): string => {
  const crypto = require('crypto');
  return crypto.createHash('sha256').update(data).digest('hex');
};

export const sleep = (ms: number): Promise<void> => {
  return new Promise(resolve => setTimeout(resolve, ms));
};
