import {
  Sequelize,
  DataTypes,
  Model,
  InferAttributes,
  InferCreationAttributes,
  CreationOptional,
} from "sequelize";
import type { AuthorizationRecordStatus } from "@/types";
import {
  decryptSensitiveUrl,
  encryptSensitiveUrl,
} from "@/lib/utils/sensitive-url-crypto";

export class AuthorizationRecord extends Model<
  InferAttributes<AuthorizationRecord>,
  InferCreationAttributes<AuthorizationRecord>
> {
  declare id: CreationOptional<string>;
  declare votingEntityId: string;
  declare required: CreationOptional<boolean>;
  declare reasonRequired: string | null;
  declare designatedVoterContactId: string | null;
  declare entityTypeAtFiling: string | null;
  declare documentFileUrl: string | null;
  declare dateReceived: string | null;
  declare status: AuthorizationRecordStatus;
  declare effectiveDate: string | null;
  declare expirationDate: string | null;
  declare signedDate: string | null;
  declare supersedesRecordId: string | null;
  declare rejectionReason: string | null;
  declare createdBy: string | null;
  declare createdAt: CreationOptional<Date>;
  declare updatedAt: CreationOptional<Date>;
}

export function initAuthorizationRecordModel(sequelize: Sequelize) {
  AuthorizationRecord.init(
    {
      id: {
        type: DataTypes.UUID,
        defaultValue: DataTypes.UUIDV4,
        primaryKey: true,
      },
      votingEntityId: { type: DataTypes.UUID, allowNull: false },
      required: {
        type: DataTypes.BOOLEAN,
        allowNull: false,
        defaultValue: true,
      },
      reasonRequired: { type: DataTypes.TEXT, allowNull: true },
      designatedVoterContactId: { type: DataTypes.UUID, allowNull: true },
      entityTypeAtFiling: { type: DataTypes.STRING(64), allowNull: true },
      documentFileUrl: {
        type: DataTypes.STRING(1024),
        allowNull: true,
        get() {
          const raw = this.getDataValue("documentFileUrl");
          try {
            return decryptSensitiveUrl(raw);
          } catch {
            return raw;
          }
        },
        set(value: string | null) {
          this.setDataValue("documentFileUrl", encryptSensitiveUrl(value));
        },
      },
      dateReceived: { type: DataTypes.DATEONLY, allowNull: true },
      status: {
        type: DataTypes.ENUM("valid", "missing", "rejected", "superseded"),
        allowNull: false,
        defaultValue: "missing",
      },
      effectiveDate: { type: DataTypes.DATEONLY, allowNull: true },
      expirationDate: { type: DataTypes.DATEONLY, allowNull: true },
      signedDate: { type: DataTypes.DATEONLY, allowNull: true },
      supersedesRecordId: { type: DataTypes.UUID, allowNull: true },
      rejectionReason: { type: DataTypes.TEXT, allowNull: true },
      createdBy: { type: DataTypes.UUID, allowNull: true },
      createdAt: DataTypes.DATE,
      updatedAt: DataTypes.DATE,
    },
    {
      sequelize,
      modelName: "AuthorizationRecord",
      tableName: "AuthorizationRecords",
    }
  );
  return AuthorizationRecord;
}
