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

interface ClaimInvoiceAttributes {
  invoiceId: string;
  requestId: string;
  invoiceNumber?: string;
  dmsNumber?: string;
  invoiceDate?: Date;
  amount: number;
  status: string;
  irn?: string | null;
  ackNo?: string | null;
  ackDate?: Date | null;
  signedInvoice?: string | null;
  signedInvoiceUrl?: string | null;
  dealerClaimNumber?: string | null;
  dealerClaimDate?: Date | null;
  billingNo?: string | null;
  billingDate?: Date | null;
  taxableValue?: number | null;
  cgstTotal?: number | null;
  sgstTotal?: number | null;
  igstTotal?: number | null;
  utgstTotal?: number | null;
  cessTotal?: number | null;
  tcsAmt?: number | null;
  roundOffAmt?: number | null;
  placeOfSupply?: string | null;
  totalValueInWords?: string | null;
  taxValueInWords?: string | null;
  creditNature?: string | null;
  consignorGsin?: string | null;
  gstinDate?: Date | null;
  filePath?: string | null;
  qrCode?: string | null;
  qrImage?: string | null;
  pwcResponse?: any;
  irpResponse?: any;
  errorMessage?: string;
  wfmPushStatus?: 'PENDING' | 'SUCCESS' | 'FAILED';
  wfmPushError?: string | null;
  generatedAt?: Date;
  description?: string;
  createdAt: Date;
  updatedAt: Date;
}

interface ClaimInvoiceCreationAttributes extends Optional<ClaimInvoiceAttributes, 'invoiceId' | 'invoiceNumber' | 'dmsNumber' | 'invoiceDate' | 'irn' | 'ackNo' | 'ackDate' | 'signedInvoice' | 'signedInvoiceUrl' | 'dealerClaimNumber' | 'dealerClaimDate' | 'billingNo' | 'billingDate' | 'taxableValue' | 'cgstTotal' | 'sgstTotal' | 'igstTotal' | 'utgstTotal' | 'cessTotal' | 'tcsAmt' | 'roundOffAmt' | 'placeOfSupply' | 'totalValueInWords' | 'taxValueInWords' | 'creditNature' | 'consignorGsin' | 'gstinDate' | 'filePath' | 'qrCode' | 'qrImage' | 'pwcResponse' | 'irpResponse' | 'errorMessage' | 'wfmPushStatus' | 'wfmPushError' | 'generatedAt' | 'description' | 'createdAt' | 'updatedAt'> { }

class ClaimInvoice extends Model<ClaimInvoiceAttributes, ClaimInvoiceCreationAttributes> implements ClaimInvoiceAttributes {
  public invoiceId!: string;
  public requestId!: string;
  public invoiceNumber?: string;
  public dmsNumber?: string;
  public invoiceDate?: Date;
  public amount!: number;
  public status!: string;
  public irn?: string | null;
  public ackNo?: string | null;
  public ackDate?: Date | null;
  public signedInvoice?: string | null;
  public signedInvoiceUrl?: string | null;
  public dealerClaimNumber?: string | null;
  public dealerClaimDate?: Date | null;
  public billingNo?: string | null;
  public billingDate?: Date | null;
  public taxableValue?: number | null;
  public cgstTotal?: number | null;
  public sgstTotal?: number | null;
  public igstTotal?: number | null;
  public utgstTotal?: number | null;
  public cessTotal?: number | null;
  public tcsAmt?: number | null;
  public roundOffAmt?: number | null;
  public placeOfSupply?: string | null;
  public totalValueInWords?: string | null;
  public taxValueInWords?: string | null;
  public creditNature?: string | null;
  public consignorGsin?: string | null;
  public gstinDate?: Date | null;
  public filePath?: string | null;
  public qrCode?: string | null;
  public qrImage?: string | null;
  public pwcResponse?: any;
  public irpResponse?: any;
  public errorMessage?: string;
  public wfmPushStatus?: 'PENDING' | 'SUCCESS' | 'FAILED';
  public wfmPushError?: string | null;
  public generatedAt?: Date;
  public description?: string;
  public createdAt!: Date;
  public updatedAt!: Date;
}

ClaimInvoice.init(
  {
    invoiceId: {
      type: DataTypes.UUID,
      defaultValue: DataTypes.UUIDV4,
      primaryKey: true,
      field: 'invoice_id',
    },
    requestId: {
      type: DataTypes.UUID,
      allowNull: false,
      unique: true,
      field: 'request_id',
      references: {
        model: 'workflow_requests',
        key: 'request_id',
      },
      onDelete: 'CASCADE',
      onUpdate: 'CASCADE',
    },
    invoiceNumber: {
      type: DataTypes.STRING(100),
      allowNull: true,
      field: 'invoice_number',
    },
    dmsNumber: {
      type: DataTypes.STRING(100),
      allowNull: true,
      field: 'dms_number',
    },
    invoiceDate: {
      type: DataTypes.DATEONLY,
      allowNull: true,
      field: 'invoice_date',
    },
    amount: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: false,
      field: 'invoice_amount',
    },
    status: {
      type: DataTypes.STRING(50),
      allowNull: false,
      defaultValue: 'PENDING',
      field: 'generation_status'
    },
    irn: {
      type: DataTypes.STRING(500),
      allowNull: true
    },
    ackNo: {
      type: DataTypes.STRING(255),
      allowNull: true,
      field: 'ack_no'
    },
    ackDate: {
      type: DataTypes.DATE,
      allowNull: true,
      field: 'ack_date'
    },
    signedInvoice: {
      type: DataTypes.TEXT,
      allowNull: true,
      field: 'signed_invoice'
    },
    signedInvoiceUrl: {
      type: DataTypes.STRING(500),
      allowNull: true,
      field: 'signed_invoice_url'
    },
    dealerClaimNumber: {
      type: DataTypes.STRING(100),
      allowNull: true,
      field: 'dealer_claim_number'
    },
    dealerClaimDate: {
      type: DataTypes.DATEONLY,
      allowNull: true,
      field: 'dealer_claim_date'
    },
    billingNo: {
      type: DataTypes.STRING(100),
      allowNull: true,
      field: 'billing_no'
    },
    billingDate: {
      type: DataTypes.DATEONLY,
      allowNull: true,
      field: 'billing_date'
    },
    taxableValue: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      field: 'taxable_value'
    },
    cgstTotal: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      field: 'cgst_total'
    },
    sgstTotal: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      field: 'sgst_total'
    },
    igstTotal: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      field: 'igst_total'
    },
    utgstTotal: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      field: 'utgst_total'
    },
    cessTotal: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      field: 'cess_total'
    },
    tcsAmt: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      field: 'tcs_amt'
    },
    roundOffAmt: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: true,
      field: 'round_off_amt'
    },
    placeOfSupply: {
      type: DataTypes.STRING(255),
      allowNull: true,
      field: 'place_of_supply'
    },
    totalValueInWords: {
      type: DataTypes.STRING(500),
      allowNull: true,
      field: 'total_value_in_words'
    },
    taxValueInWords: {
      type: DataTypes.STRING(500),
      allowNull: true,
      field: 'tax_value_in_words'
    },
    creditNature: {
      type: DataTypes.STRING(100),
      allowNull: true,
      field: 'credit_nature'
    },
    consignorGsin: {
      type: DataTypes.STRING(255),
      allowNull: true,
      field: 'consignor_gsin'
    },
    gstinDate: {
      type: DataTypes.DATEONLY,
      allowNull: true,
      field: 'gstin_date'
    },
    filePath: {
      type: DataTypes.STRING(500),
      allowNull: true,
      field: 'file_path'
    },
    qrCode: {
      type: DataTypes.TEXT,
      allowNull: true,
      field: 'qr_code'
    },
    qrImage: {
      type: DataTypes.TEXT,
      allowNull: true,
      field: 'qr_image'
    },
    pwcResponse: {
      type: DataTypes.JSON,
      allowNull: true,
      field: 'pwc_response'
    },
    irpResponse: {
      type: DataTypes.JSON,
      allowNull: true,
      field: 'irp_response'
    },
    errorMessage: {
      type: DataTypes.TEXT,
      allowNull: true,
      field: 'error_message',
    },
    wfmPushStatus: {
      type: DataTypes.STRING(20),
      allowNull: true,
      defaultValue: 'PENDING',
      field: 'wfm_push_status'
    },
    wfmPushError: {
      type: DataTypes.TEXT,
      allowNull: true,
      field: 'wfm_push_error'
    },
    generatedAt: {
      type: DataTypes.DATE,
      allowNull: true,
      field: 'generated_at',
    },
    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: 'ClaimInvoice',
    tableName: 'claim_invoices',
    timestamps: true,
    createdAt: 'created_at',
    updatedAt: 'updated_at',
    indexes: [
      { unique: true, fields: ['request_id'], name: 'idx_claim_invoices_request_id' },
      { fields: ['invoice_number'], name: 'idx_claim_invoices_invoice_number' },
      { fields: ['dms_number'], name: 'idx_claim_invoices_dms_number' },
      { fields: ['generation_status'], name: 'idx_claim_invoices_status' },
    ],
  }
);

WorkflowRequest.hasOne(ClaimInvoice, {
  as: 'claimInvoice',
  foreignKey: 'requestId',
  sourceKey: 'requestId',
});

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

// Note: hasMany association with ClaimCreditNote is defined in ClaimCreditNote.ts
// to avoid circular dependency issues

export { ClaimInvoice };

