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;
  gstRate?: number;
  gstAmt?: number;
  cgstRate?: number;
  cgstAmt?: number;
  sgstRate?: number;
  sgstAmt?: number;
  igstRate?: number;
  igstAmt?: number;
  utgstRate?: number;
  utgstAmt?: number;
  cessRate?: number;
  cessAmt?: number;
  totalAmt?: 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' | 'gstRate' | 'gstAmt' | 'cgstRate' | 'cgstAmt' | 'sgstRate' | 'sgstAmt' | 'igstRate' | 'igstAmt' | 'utgstRate' | 'utgstAmt' | 'cessRate' | 'cessAmt' | 'totalAmt' | '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 gstRate?: number;
  public gstAmt?: number;
  public cgstRate?: number;
  public cgstAmt?: number;
  public sgstRate?: number;
  public sgstAmt?: number;
  public igstRate?: number;
  public igstAmt?: number;
  public utgstRate?: number;
  public utgstAmt?: number;
  public cessRate?: number;
  public cessAmt?: number;
  public totalAmt?: 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'
    },
    gstRate: {
      type: DataTypes.DECIMAL(5, 2),
      allowNull: true,
      field: 'gst_rate'
    },
    gstAmt: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      field: 'gst_amt'
    },
    cgstRate: {
      type: DataTypes.DECIMAL(5, 2),
      allowNull: true,
      field: 'cgst_rate'
    },
    cgstAmt: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      field: 'cgst_amt'
    },
    sgstRate: {
      type: DataTypes.DECIMAL(5, 2),
      allowNull: true,
      field: 'sgst_rate'
    },
    sgstAmt: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      field: 'sgst_amt'
    },
    igstRate: {
      type: DataTypes.DECIMAL(5, 2),
      allowNull: true,
      field: 'igst_rate'
    },
    igstAmt: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      field: 'igst_amt'
    },
    utgstRate: {
      type: DataTypes.DECIMAL(5, 2),
      allowNull: true,
      field: 'utgst_rate'
    },
    utgstAmt: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      field: 'utgst_amt'
    },
    cessRate: {
      type: DataTypes.DECIMAL(5, 2),
      allowNull: true,
      field: 'cess_rate'
    },
    cessAmt: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      field: 'cess_amt'
    },
    totalAmt: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      field: 'total_amt'
    },
    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 };

