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

interface DocumentAttributes {
  documentId: string;
  requestId: string;
  uploadedBy: string;
  fileName: string;
  originalFileName: string;
  fileType: string;
  fileExtension: string;
  fileSize: number;
  filePath: string;
  storageUrl?: string;
  mimeType: string;
  checksum: string;
  isGoogleDoc: boolean;
  googleDocUrl?: string;
  category: string;
  version: number;
  parentDocumentId?: string;
  isDeleted: boolean;
  downloadCount: number;
  uploadedAt: Date;
}

interface DocumentCreationAttributes extends Optional<DocumentAttributes, 'documentId' | 'storageUrl' | 'googleDocUrl' | 'parentDocumentId' | 'uploadedAt'> {}

class Document extends Model<DocumentAttributes, DocumentCreationAttributes> implements DocumentAttributes {
  public documentId!: string;
  public requestId!: string;
  public uploadedBy!: string;
  public fileName!: string;
  public originalFileName!: string;
  public fileType!: string;
  public fileExtension!: string;
  public fileSize!: number;
  public filePath!: string;
  public storageUrl?: string;
  public mimeType!: string;
  public checksum!: string;
  public isGoogleDoc!: boolean;
  public googleDocUrl?: string;
  public category!: string;
  public version!: number;
  public parentDocumentId?: string;
  public isDeleted!: boolean;
  public downloadCount!: number;
  public uploadedAt!: Date;

  // Associations
  public request?: WorkflowRequest;
  public uploader?: User;
  public parentDocument?: Document;
}

Document.init(
  {
    documentId: {
      type: DataTypes.UUID,
      defaultValue: DataTypes.UUIDV4,
      primaryKey: true,
      field: 'document_id'
    },
    requestId: {
      type: DataTypes.UUID,
      allowNull: false,
      field: 'request_id',
      references: {
        model: 'workflow_requests',
        key: 'request_id'
      }
    },
    uploadedBy: {
      type: DataTypes.UUID,
      allowNull: false,
      field: 'uploaded_by',
      references: {
        model: 'users',
        key: 'user_id'
      }
    },
    fileName: {
      type: DataTypes.STRING(255),
      allowNull: false,
      field: 'file_name'
    },
    originalFileName: {
      type: DataTypes.STRING(255),
      allowNull: false,
      field: 'original_file_name'
    },
    fileType: {
      type: DataTypes.STRING(100),
      allowNull: false,
      field: 'file_type'
    },
    fileExtension: {
      type: DataTypes.STRING(10),
      allowNull: false,
      field: 'file_extension'
    },
    fileSize: {
      type: DataTypes.BIGINT,
      allowNull: false,
      field: 'file_size',
      validate: {
        max: 10485760 // 10MB limit
      }
    },
    filePath: {
      type: DataTypes.STRING(500),
      allowNull: false,
      field: 'file_path'
    },
    storageUrl: {
      type: DataTypes.STRING(500),
      allowNull: true,
      field: 'storage_url'
    },
    mimeType: {
      type: DataTypes.STRING(100),
      allowNull: false,
      field: 'mime_type'
    },
    checksum: {
      type: DataTypes.STRING(64),
      allowNull: false
    },
    isGoogleDoc: {
      type: DataTypes.BOOLEAN,
      defaultValue: false,
      field: 'is_google_doc'
    },
    googleDocUrl: {
      type: DataTypes.STRING(500),
      allowNull: true,
      field: 'google_doc_url'
    },
    category: {
      type: DataTypes.ENUM('SUPPORTING', 'APPROVAL', 'REFERENCE', 'FINAL', 'OTHER'),
      defaultValue: 'OTHER'
    },
    version: {
      type: DataTypes.INTEGER,
      defaultValue: 1
    },
    parentDocumentId: {
      type: DataTypes.UUID,
      allowNull: true,
      field: 'parent_document_id',
      references: {
        model: 'documents',
        key: 'document_id'
      }
    },
    isDeleted: {
      type: DataTypes.BOOLEAN,
      defaultValue: false,
      field: 'is_deleted'
    },
    downloadCount: {
      type: DataTypes.INTEGER,
      defaultValue: 0,
      field: 'download_count'
    },
    uploadedAt: {
      type: DataTypes.DATE,
      allowNull: false,
      defaultValue: DataTypes.NOW,
      field: 'uploaded_at'
    }
  },
  {
    sequelize,
    modelName: 'Document',
    tableName: 'documents',
    timestamps: false,
    indexes: [
      {
        fields: ['request_id']
      },
      {
        fields: ['uploaded_by']
      },
      {
        fields: ['category']
      },
      {
        fields: ['is_deleted']
      }
    ]
  }
);

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

Document.belongsTo(User, {
  as: 'uploader',
  foreignKey: 'uploadedBy',
  targetKey: 'userId'
});

Document.belongsTo(Document, {
  as: 'parentDocument',
  foreignKey: 'parentDocumentId',
  targetKey: 'documentId'
});

export { Document };
