import { DataTypes, Model, Optional } from 'sequelize';
import { sequelize } from '@config/database';
import { User } from './User';
import { WorkflowRequest } from './WorkflowRequest';
import { ApprovalStatus } from '../types/common.types';

interface ApprovalLevelAttributes {
  levelId: string;
  requestId: string;
  levelNumber: number;
  levelName?: string;
  approverId: string;
  approverEmail: string;
  approverName: string;
  tatHours: number;
  tatDays: number;
  status: ApprovalStatus;
  levelStartTime?: Date;
  levelEndTime?: Date;
  actionDate?: Date;
  comments?: string;
  rejectionReason?: string;
  breachReason?: string;
  isFinalApprover: boolean;
  elapsedHours: number;
  remainingHours: number;
  tatPercentageUsed: number;
  tat50AlertSent: boolean;
  tat75AlertSent: boolean;
  tatBreached: boolean;
  tatStartTime?: Date;
  isPaused: boolean;
  pausedAt?: Date;
  pausedBy?: string;
  pauseReason?: string;
  pauseResumeDate?: Date;
  pauseTatStartTime?: Date;
  pauseElapsedHours?: number;
  createdAt: Date;
  updatedAt: Date;
}

interface ApprovalLevelCreationAttributes extends Optional<ApprovalLevelAttributes, 'levelId' | 'levelName' | 'levelStartTime' | 'levelEndTime' | 'actionDate' | 'comments' | 'rejectionReason' | 'breachReason' | 'tat50AlertSent' | 'tat75AlertSent' | 'tatBreached' | 'tatStartTime' | 'tatDays' | 'isPaused' | 'pausedAt' | 'pausedBy' | 'pauseReason' | 'pauseResumeDate' | 'pauseTatStartTime' | 'pauseElapsedHours' | 'createdAt' | 'updatedAt'> {}

class ApprovalLevel extends Model<ApprovalLevelAttributes, ApprovalLevelCreationAttributes> implements ApprovalLevelAttributes {
  public levelId!: string;
  public requestId!: string;
  public levelNumber!: number;
  public levelName?: string;
  public approverId!: string;
  public approverEmail!: string;
  public approverName!: string;
  public tatHours!: number;
  public tatDays!: number;
  public status!: ApprovalStatus;
  public levelStartTime?: Date;
  public levelEndTime?: Date;
  public actionDate?: Date;
  public comments?: string;
  public rejectionReason?: string;
  public breachReason?: string;
  public isFinalApprover!: boolean;
  public elapsedHours!: number;
  public remainingHours!: number;
  public tatPercentageUsed!: number;
  public tat50AlertSent!: boolean;
  public tat75AlertSent!: boolean;
  public tatBreached!: boolean;
  public tatStartTime?: Date;
  public isPaused!: boolean;
  public pausedAt?: Date;
  public pausedBy?: string;
  public pauseReason?: string;
  public pauseResumeDate?: Date;
  public pauseTatStartTime?: Date;
  public pauseElapsedHours?: number;
  public createdAt!: Date;
  public updatedAt!: Date;

  // Associations
  public request?: WorkflowRequest;
  public approver?: User;
}

ApprovalLevel.init(
  {
    levelId: {
      type: DataTypes.UUID,
      defaultValue: DataTypes.UUIDV4,
      primaryKey: true,
      field: 'level_id'
    },
    requestId: {
      type: DataTypes.UUID,
      allowNull: false,
      field: 'request_id',
      references: {
        model: 'workflow_requests',
        key: 'request_id'
      }
    },
    levelNumber: {
      type: DataTypes.INTEGER,
      allowNull: false,
      field: 'level_number'
    },
    levelName: {
      type: DataTypes.STRING(100),
      allowNull: true,
      field: 'level_name'
    },
    approverId: {
      type: DataTypes.UUID,
      allowNull: false,
      field: 'approver_id',
      references: {
        model: 'users',
        key: 'user_id'
      }
    },
    approverEmail: {
      type: DataTypes.STRING(255),
      allowNull: false,
      field: 'approver_email'
    },
    approverName: {
      type: DataTypes.STRING(200),
      allowNull: false,
      field: 'approver_name'
    },
    tatHours: {
      type: DataTypes.DECIMAL(10, 2),
      allowNull: false,
      field: 'tat_hours'
    },
    tatDays: {
      type: DataTypes.INTEGER,
      allowNull: true,
      field: 'tat_days'
      // This is a GENERATED STORED column in production DB (calculated as CEIL(tat_hours / 24.0))
      // Database will auto-calculate this value - do NOT pass it during INSERT/UPDATE operations
    },
    status: {
      type: DataTypes.ENUM('PENDING', 'IN_PROGRESS', 'APPROVED', 'REJECTED', 'SKIPPED', 'PAUSED'),
      defaultValue: 'PENDING'
    },
    levelStartTime: {
      type: DataTypes.DATE,
      allowNull: true,
      field: 'level_start_time'
    },
    levelEndTime: {
      type: DataTypes.DATE,
      allowNull: true,
      field: 'level_end_time'
    },
    actionDate: {
      type: DataTypes.DATE,
      allowNull: true,
      field: 'action_date'
    },
    comments: {
      type: DataTypes.TEXT,
      allowNull: true
    },
    rejectionReason: {
      type: DataTypes.TEXT,
      allowNull: true,
      field: 'rejection_reason'
    },
    breachReason: {
      type: DataTypes.TEXT,
      allowNull: true,
      field: 'breach_reason',
      comment: 'Reason for TAT breach - can contain paragraph-length text'
    },
    isFinalApprover: {
      type: DataTypes.BOOLEAN,
      defaultValue: false,
      field: 'is_final_approver'
    },
    elapsedHours: {
      type: DataTypes.DECIMAL(10, 2),
      defaultValue: 0,
      field: 'elapsed_hours'
    },
    remainingHours: {
      type: DataTypes.DECIMAL(10, 2),
      defaultValue: 0,
      field: 'remaining_hours'
    },
    tatPercentageUsed: {
      type: DataTypes.DECIMAL(5, 2),
      defaultValue: 0,
      field: 'tat_percentage_used'
    },
    tat50AlertSent: {
      type: DataTypes.BOOLEAN,
      defaultValue: false,
      field: 'tat50_alert_sent'
    },
    tat75AlertSent: {
      type: DataTypes.BOOLEAN,
      defaultValue: false,
      field: 'tat75_alert_sent'
    },
    tatBreached: {
      type: DataTypes.BOOLEAN,
      defaultValue: false,
      field: 'tat_breached'
    },
    tatStartTime: {
      type: DataTypes.DATE,
      allowNull: true,
      field: 'tat_start_time'
    },
    isPaused: {
      type: DataTypes.BOOLEAN,
      defaultValue: false,
      field: 'is_paused'
    },
    pausedAt: {
      type: DataTypes.DATE,
      allowNull: true,
      field: 'paused_at'
    },
    pausedBy: {
      type: DataTypes.UUID,
      allowNull: true,
      field: 'paused_by',
      references: {
        model: 'users',
        key: 'user_id'
      }
    },
    pauseReason: {
      type: DataTypes.TEXT,
      allowNull: true,
      field: 'pause_reason'
    },
    pauseResumeDate: {
      type: DataTypes.DATE,
      allowNull: true,
      field: 'pause_resume_date'
    },
    pauseTatStartTime: {
      type: DataTypes.DATE,
      allowNull: true,
      field: 'pause_tat_start_time'
    },
    pauseElapsedHours: {
      type: DataTypes.DECIMAL(10, 2),
      allowNull: true,
      field: 'pause_elapsed_hours'
    },
    createdAt: {
      type: DataTypes.DATE,
      allowNull: false,
      defaultValue: DataTypes.NOW,
      field: 'created_at'
    },
    updatedAt: {
      type: DataTypes.DATE,
      allowNull: false,
      defaultValue: DataTypes.NOW,
      field: 'updated_at'
    }
  },
  {
    sequelize,
    modelName: 'ApprovalLevel',
    tableName: 'approval_levels',
    timestamps: true,
    createdAt: 'created_at',
    updatedAt: 'updated_at',
    indexes: [
      {
        fields: ['request_id']
      },
      {
        fields: ['approver_id']
      },
      {
        fields: ['status']
      },
      {
        unique: true,
        fields: ['request_id', 'level_number']
      }
    ]
  }
);

// Associations
ApprovalLevel.belongsTo(WorkflowRequest, {
  as: 'request',
  foreignKey: 'requestId',
  targetKey: 'requestId'
});

ApprovalLevel.belongsTo(User, {
  as: 'approver',
  foreignKey: 'approverId',
  targetKey: 'userId'
});

export { ApprovalLevel };
