import { Model, DataTypes, Sequelize, Op } from 'sequelize';
import { CONSTITUTIONAL_CHANGE_TYPES, CONSTITUTIONAL_STAGES } from '../../../../common/config/constants.js';

export interface ConstitutionalChangeAttributes {
    id: string;
    requestId: string;
    outletId: string | null;
    dealerId: string;
    changeType: typeof CONSTITUTIONAL_CHANGE_TYPES[keyof typeof CONSTITUTIONAL_CHANGE_TYPES];
    description: string;
    currentConstitution: string | null;
    oldValue: string | null;
    newValue: string | null;
    currentStage: typeof CONSTITUTIONAL_STAGES[keyof typeof CONSTITUTIONAL_STAGES];
    status: string;
    progressPercentage: number;
    metadata: any;
    documents: any[];
    timeline: any[];
}

export interface ConstitutionalChangeInstance extends Model<ConstitutionalChangeAttributes>, ConstitutionalChangeAttributes { }

export default (sequelize: Sequelize) => {
    const ConstitutionalChange = sequelize.define<ConstitutionalChangeInstance>('ConstitutionalChange', {
        id: {
            type: DataTypes.UUID,
            defaultValue: DataTypes.UUIDV4,
            primaryKey: true
        },
        requestId: {
            type: DataTypes.STRING,
            unique: true,
            allowNull: false
        },
        outletId: {
            type: DataTypes.UUID,
            allowNull: true,
            references: {
                model: 'outlets',
                key: 'id'
            }
        },
        dealerId: {
            type: DataTypes.UUID,
            allowNull: false,
            references: {
                model: 'users',
                key: 'id'
            }
        },
        changeType: {
            type: DataTypes.ENUM(...Object.values(CONSTITUTIONAL_CHANGE_TYPES)),
            allowNull: false
        },
        description: {
            type: DataTypes.TEXT,
            allowNull: false
        },
        currentConstitution: {
            type: DataTypes.STRING,
            allowNull: true
        },
        oldValue: {
            type: DataTypes.STRING,
            allowNull: true
        },
        newValue: {
            type: DataTypes.STRING,
            allowNull: true
        },
        currentStage: {
            type: DataTypes.ENUM(...Object.values(CONSTITUTIONAL_STAGES)),
            defaultValue: CONSTITUTIONAL_STAGES.ASM_REVIEW
        },

        status: {
            type: DataTypes.STRING,
            defaultValue: 'Pending'
        },
        progressPercentage: {
            type: DataTypes.INTEGER,
            defaultValue: 0
        },
        metadata: {
            type: DataTypes.JSON,
            defaultValue: {}
        },
        documents: {
            type: DataTypes.JSON,
            defaultValue: []
        },
        timeline: {
            type: DataTypes.JSON,
            defaultValue: []
        }
    }, {
        tableName: 'constitutional_changes',
        timestamps: true,
        indexes: [
            { fields: ['requestId'] },
            { fields: ['outletId'] },
            { fields: ['dealerId'] },
            { fields: ['currentStage'] },
            /** SRS §12.2 — at most one non-terminal request per dealer (PostgreSQL partial unique index). */
            {
                name: 'uq_constitutional_open_per_dealer',
                unique: true,
                fields: ['dealerId'],
                where: {
                    status: {
                        [Op.notIn]: ['Completed', 'Closed', 'Rejected', 'Revoked']
                    }
                }
            }
        ]
    });

    (ConstitutionalChange as any).associate = (models: any) => {
        ConstitutionalChange.belongsTo(models.Outlet, {
            foreignKey: 'outletId',
            as: 'outlet'
        });
        ConstitutionalChange.belongsTo(models.User, {
            foreignKey: 'dealerId',
            as: 'dealer'
        });
        ConstitutionalChange.hasMany(models.ConstitutionalDocument, {
            foreignKey: 'constitutionalChangeId',
            as: 'uploadedDocuments'
        });
        ConstitutionalChange.hasMany(models.Worknote, {
            foreignKey: 'requestId',
            as: 'worknotes',
            scope: { requestType: 'constitutional' },
            constraints: false
        });
        ConstitutionalChange.hasMany(models.RequestParticipant, {
            foreignKey: 'requestId',
            as: 'participants',
            scope: { requestType: 'constitutional' },
            constraints: false
        });
    };

    return ConstitutionalChange;
};
