import {
  Sequelize,
  DataTypes,
  Model,
  InferAttributes,
  InferCreationAttributes,
  CreationOptional,
} from "sequelize";
import type { EligibilityStatus, ProxyType, VoterType } from "@/types";

export class ElectionVoterRoll extends Model<
  InferAttributes<ElectionVoterRoll>,
  InferCreationAttributes<ElectionVoterRoll>
> {
  declare id: CreationOptional<string>;
  declare electionId: string;
  declare voterType: VoterType;
  declare voterRefId: string;
  declare weight: CreationOptional<number>;
  declare eligibilityStatus: EligibilityStatus;
  declare proxyAssignedToRollId: string | null;
  declare proxyType: ProxyType | null;
  declare directedSelections: Record<string, unknown> | null;
  declare invitationSentAt: Date | null;
  declare hasVoted: CreationOptional<boolean>;
  declare votedAt: Date | null;
  declare createdAt: CreationOptional<Date>;
  declare updatedAt: CreationOptional<Date>;
}

export function initElectionVoterRollModel(sequelize: Sequelize) {
  ElectionVoterRoll.init(
    {
      id: {
        type: DataTypes.UUID,
        defaultValue: DataTypes.UUIDV4,
        primaryKey: true,
      },
      electionId: { type: DataTypes.UUID, allowNull: false },
      voterType: {
        type: DataTypes.ENUM("contact", "voting_entity", "user"),
        allowNull: false,
      },
      voterRefId: { type: DataTypes.UUID, allowNull: false },
      weight: {
        type: DataTypes.DECIMAL(10, 4),
        allowNull: false,
        defaultValue: 1,
        get() {
          const raw = this.getDataValue("weight");
          return raw == null ? 1 : Number(raw);
        },
      },
      eligibilityStatus: {
        type: DataTypes.ENUM("eligible", "blocked", "pending_authorization"),
        allowNull: false,
        defaultValue: "eligible",
      },
      proxyAssignedToRollId: { type: DataTypes.UUID, allowNull: true },
      proxyType: {
        type: DataTypes.ENUM("general", "directed"),
        allowNull: true,
      },
      directedSelections: { type: DataTypes.JSON, allowNull: true },
      invitationSentAt: { type: DataTypes.DATE, allowNull: true },
      hasVoted: {
        type: DataTypes.BOOLEAN,
        allowNull: false,
        defaultValue: false,
      },
      votedAt: { type: DataTypes.DATE, allowNull: true },
      createdAt: DataTypes.DATE,
      updatedAt: DataTypes.DATE,
    },
    { sequelize, modelName: "ElectionVoterRoll", tableName: "ElectionVoterRoll" }
  );
  return ElectionVoterRoll;
}
