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

export enum BudgetStatus {
  DRAFT = 'DRAFT',
  PROPOSED = 'PROPOSED',
  APPROVED = 'APPROVED',
  BLOCKED = 'BLOCKED',
  CLOSED = 'CLOSED',
  SETTLED = 'SETTLED'
}

interface ClaimBudgetTrackingAttributes {
  budgetId: string;
  requestId: string;
  // Initial Budget
  initialEstimatedBudget?: number;
  // Proposal Budget
  proposalEstimatedBudget?: number;
  proposalSubmittedAt?: Date;
  // Approved Budget
  approvedBudget?: number;
  approvedAt?: Date;
  approvedBy?: string;
  // IO Blocked Budget
  ioBlockedAmount?: number;
  ioBlockedAt?: Date;
  // Closed Expenses
  closedExpenses?: number;
  taxableClosedExpenses?: number;
  closedExpensesSubmittedAt?: Date;
  // Final Claim Amount
  finalClaimAmount?: number;
  finalClaimAmountApprovedAt?: Date;
  finalClaimAmountApprovedBy?: string;
  // Credit Note
  creditNoteAmount?: number;
  creditNoteIssuedAt?: Date;
  // Status & Metadata
  budgetStatus: BudgetStatus;
  currency: string;
  varianceAmount?: number;
  variancePercentage?: number;
  // Audit
  lastModifiedBy?: string;
  lastModifiedAt?: Date;
  modificationReason?: string;
  createdAt: Date;
  updatedAt: Date;
}

interface ClaimBudgetTrackingCreationAttributes extends Optional<ClaimBudgetTrackingAttributes, 'budgetId' | 'initialEstimatedBudget' | 'proposalEstimatedBudget' | 'proposalSubmittedAt' | 'approvedBudget' | 'approvedAt' | 'approvedBy' | 'ioBlockedAmount' | 'ioBlockedAt' | 'closedExpenses' | 'taxableClosedExpenses' | 'closedExpensesSubmittedAt' | 'finalClaimAmount' | 'finalClaimAmountApprovedAt' | 'finalClaimAmountApprovedBy' | 'creditNoteAmount' | 'creditNoteIssuedAt' | 'varianceAmount' | 'variancePercentage' | 'lastModifiedBy' | 'lastModifiedAt' | 'modificationReason' | 'budgetStatus' | 'currency' | 'createdAt' | 'updatedAt'> { }

class ClaimBudgetTracking extends Model<ClaimBudgetTrackingAttributes, ClaimBudgetTrackingCreationAttributes> implements ClaimBudgetTrackingAttributes {
  public budgetId!: string;
  public requestId!: string;
  public initialEstimatedBudget?: number;
  public proposalEstimatedBudget?: number;
  public proposalSubmittedAt?: Date;
  public approvedBudget?: number;
  public approvedAt?: Date;
  public approvedBy?: string;
  public ioBlockedAmount?: number;
  public ioBlockedAt?: Date;
  public closedExpenses?: number;
  public taxableClosedExpenses?: number;
  public closedExpensesSubmittedAt?: Date;
  public finalClaimAmount?: number;
  public finalClaimAmountApprovedAt?: Date;
  public finalClaimAmountApprovedBy?: string;
  public creditNoteAmount?: number;
  public creditNoteIssuedAt?: Date;
  public budgetStatus!: BudgetStatus;
  public currency!: string;
  public varianceAmount?: number;
  public variancePercentage?: number;
  public lastModifiedBy?: string;
  public lastModifiedAt?: Date;
  public modificationReason?: string;
  public createdAt!: Date;
  public updatedAt!: Date;

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

ClaimBudgetTracking.init(
  {
    budgetId: {
      type: DataTypes.UUID,
      defaultValue: DataTypes.UUIDV4,
      primaryKey: true,
      field: 'budget_id'
    },
    requestId: {
      type: DataTypes.UUID,
      allowNull: false,
      unique: true,
      field: 'request_id',
      references: {
        model: 'workflow_requests',
        key: 'request_id'
      }
    },
    initialEstimatedBudget: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      field: 'initial_estimated_budget'
    },
    proposalEstimatedBudget: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      field: 'proposal_estimated_budget'
    },
    proposalSubmittedAt: {
      type: DataTypes.DATE,
      allowNull: true,
      field: 'proposal_submitted_at'
    },
    approvedBudget: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      field: 'approved_budget'
    },
    approvedAt: {
      type: DataTypes.DATE,
      allowNull: true,
      field: 'approved_at'
    },
    approvedBy: {
      type: DataTypes.UUID,
      allowNull: true,
      field: 'approved_by',
      references: {
        model: 'users',
        key: 'user_id'
      }
    },
    ioBlockedAmount: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      field: 'io_blocked_amount'
    },
    ioBlockedAt: {
      type: DataTypes.DATE,
      allowNull: true,
      field: 'io_blocked_at'
    },
    closedExpenses: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      field: 'closed_expenses'
    },
    closedExpensesSubmittedAt: {
      type: DataTypes.DATE,
      allowNull: true,
      field: 'closed_expenses_submitted_at'
    },
    taxableClosedExpenses: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      field: 'taxable_closed_expenses'
    },
    finalClaimAmount: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      field: 'final_claim_amount'
    },
    finalClaimAmountApprovedAt: {
      type: DataTypes.DATE,
      allowNull: true,
      field: 'final_claim_amount_approved_at'
    },
    finalClaimAmountApprovedBy: {
      type: DataTypes.UUID,
      allowNull: true,
      field: 'final_claim_amount_approved_by',
      references: {
        model: 'users',
        key: 'user_id'
      }
    },
    creditNoteAmount: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      field: 'credit_note_amount'
    },
    creditNoteIssuedAt: {
      type: DataTypes.DATE,
      allowNull: true,
      field: 'credit_note_issued_at'
    },
    budgetStatus: {
      type: DataTypes.ENUM('DRAFT', 'PROPOSED', 'APPROVED', 'BLOCKED', 'CLOSED', 'SETTLED'),
      defaultValue: 'DRAFT',
      allowNull: false,
      field: 'budget_status'
    },
    currency: {
      type: DataTypes.STRING(3),
      defaultValue: 'INR',
      allowNull: false
    },
    varianceAmount: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      field: 'variance_amount'
    },
    variancePercentage: {
      type: DataTypes.DECIMAL(5, 2),
      allowNull: true,
      field: 'variance_percentage'
    },
    lastModifiedBy: {
      type: DataTypes.UUID,
      allowNull: true,
      field: 'last_modified_by',
      references: {
        model: 'users',
        key: 'user_id'
      }
    },
    lastModifiedAt: {
      type: DataTypes.DATE,
      allowNull: true,
      field: 'last_modified_at'
    },
    modificationReason: {
      type: DataTypes.TEXT,
      allowNull: true,
      field: 'modification_reason'
    },
    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: 'ClaimBudgetTracking',
    tableName: 'claim_budget_tracking',
    timestamps: true,
    createdAt: 'created_at',
    updatedAt: 'updated_at',
    indexes: [
      {
        fields: ['request_id'],
        unique: true
      },
      {
        fields: ['budget_status']
      },
      {
        fields: ['approved_by']
      },
      {
        fields: ['final_claim_amount_approved_by']
      }
    ]
  }
);

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

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

ClaimBudgetTracking.belongsTo(User, {
  as: 'finalApprover',
  foreignKey: 'finalClaimAmountApprovedBy',
  targetKey: 'userId'
});

ClaimBudgetTracking.belongsTo(User, {
  as: 'lastModifier',
  foreignKey: 'lastModifiedBy',
  targetKey: 'userId'
});

export { ClaimBudgetTracking };

