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

interface ClaimCreditNoteAttributes {
  creditNoteId: string;
  requestId: string;
  invoiceId?: string;
  creditNoteNumber?: string;
  creditNoteDate?: Date;
  creditNoteAmount: number;
  transactionNo?: string;
  tdsAmount?: number;
  creditAmount?: number;
  sapDocumentNumber?: string;
  creditNoteFilePath?: string;
  status?: string;
  errorMessage?: string;
  confirmedBy?: string;
  confirmedAt?: Date;
  reason?: string;
  description?: string;
  createdAt: Date;
  updatedAt: Date;
}

interface ClaimCreditNoteCreationAttributes extends Optional<ClaimCreditNoteAttributes, 'creditNoteId' | 'invoiceId' | 'creditNoteNumber' | 'creditNoteDate' | 'transactionNo' | 'tdsAmount' | 'creditAmount' | 'sapDocumentNumber' | 'creditNoteFilePath' | 'status' | 'errorMessage' | 'confirmedBy' | 'confirmedAt' | 'reason' | 'description' | 'createdAt' | 'updatedAt'> { }

class ClaimCreditNote extends Model<ClaimCreditNoteAttributes, ClaimCreditNoteCreationAttributes> implements ClaimCreditNoteAttributes {
  public creditNoteId!: string;
  public requestId!: string;
  public invoiceId?: string;
  public creditNoteNumber?: string;
  public creditNoteDate?: Date;
  public creditNoteAmount!: number;
  public transactionNo?: string;
  public tdsAmount?: number;
  public creditAmount?: number;
  public sapDocumentNumber?: string;
  public creditNoteFilePath?: string;
  public status?: string;
  public errorMessage?: string;
  public confirmedBy?: string;
  public confirmedAt?: Date;
  public reason?: string;
  public description?: string;
  public createdAt!: Date;
  public updatedAt!: Date;
}

ClaimCreditNote.init(
  {
    creditNoteId: {
      type: DataTypes.UUID,
      defaultValue: DataTypes.UUIDV4,
      primaryKey: true,
      field: 'credit_note_id',
    },
    requestId: {
      type: DataTypes.UUID,
      allowNull: false,
      unique: true,
      field: 'request_id',
      references: {
        model: 'workflow_requests',
        key: 'request_id',
      },
      onDelete: 'CASCADE',
      onUpdate: 'CASCADE',
    },
    invoiceId: {
      type: DataTypes.UUID,
      allowNull: true,
      field: 'invoice_id',
      references: {
        model: 'claim_invoices',
        key: 'invoice_id',
      },
      onDelete: 'SET NULL',
      onUpdate: 'CASCADE',
    },
    creditNoteNumber: {
      type: DataTypes.STRING(100),
      allowNull: true,
      field: 'credit_note_number',
    },
    creditNoteDate: {
      type: DataTypes.DATEONLY,
      allowNull: true,
      field: 'credit_note_date',
    },
    creditNoteAmount: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: false,
      field: 'credit_amount'
    },
    transactionNo: {
      type: DataTypes.STRING(100),
      allowNull: true,
      field: 'transaction_no',
    },
    tdsAmount: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      defaultValue: 0,
      field: 'tds_amount',
    },
    creditAmount: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      defaultValue: 0,
      field: 'credit_amount',
    },
    sapDocumentNumber: {
      type: DataTypes.STRING(100),
      allowNull: true,
      field: 'sap_document_number',
    },
    creditNoteFilePath: {
      type: DataTypes.STRING(500),
      allowNull: true,
      field: 'credit_note_file_path',
    },
    status: {
      type: DataTypes.STRING(50),
      allowNull: true,
      field: 'confirmation_status',
    },
    errorMessage: {
      type: DataTypes.TEXT,
      allowNull: true,
      field: 'error_message',
    },
    confirmedBy: {
      type: DataTypes.UUID,
      allowNull: true,
      field: 'confirmed_by',
      references: {
        model: 'users',
        key: 'user_id',
      },
      onDelete: 'SET NULL',
      onUpdate: 'CASCADE',
    },
    confirmedAt: {
      type: DataTypes.DATE,
      allowNull: true,
      field: 'confirmed_at',
    },
    reason: {
      type: DataTypes.TEXT,
      allowNull: true,
      field: 'reason',
    },
    description: {
      type: DataTypes.TEXT,
      allowNull: true,
      field: 'description',
    },
    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: 'ClaimCreditNote',
    tableName: 'claim_credit_notes',
    timestamps: true,
    createdAt: 'created_at',
    updatedAt: 'updated_at',
    indexes: [
      { unique: true, fields: ['request_id'], name: 'idx_claim_credit_notes_request_id' },
      { fields: ['invoice_id'], name: 'idx_claim_credit_notes_invoice_id' },
      { fields: ['credit_note_number'], name: 'idx_claim_credit_notes_number' },
      { fields: ['sap_document_number'], name: 'idx_claim_credit_notes_sap_doc' },
      { fields: ['confirmation_status'], name: 'idx_claim_credit_notes_status' },
    ],
  }
);

WorkflowRequest.hasOne(ClaimCreditNote, {
  as: 'claimCreditNote',
  foreignKey: 'requestId',
  sourceKey: 'requestId',
});

ClaimCreditNote.belongsTo(WorkflowRequest, {
  as: 'workflowRequest',
  foreignKey: 'requestId',
  targetKey: 'requestId',
});

ClaimCreditNote.belongsTo(ClaimInvoice, {
  as: 'claimInvoice',
  foreignKey: 'invoiceId',
  targetKey: 'invoiceId',
});

ClaimInvoice.hasMany(ClaimCreditNote, {
  as: 'creditNotes',
  foreignKey: 'invoiceId',
  sourceKey: 'invoiceId',
});

export { ClaimCreditNote };

