import {
  Sequelize,
  DataTypes,
  Model,
  InferAttributes,
  InferCreationAttributes,
  CreationOptional,
} from "sequelize";
import { parseJsonColumn } from "@/lib/utils/parse-json-column";
import type {
  DomesticOptionsConfig,
  DomesticQuestionType,
} from "@/types/participant";

/** Immutable once `publishedAt` is set — edits create a new version. */
export class DomesticQuestionVersion extends Model<
  InferAttributes<DomesticQuestionVersion>,
  InferCreationAttributes<DomesticQuestionVersion>
> {
  declare id: CreationOptional<string>;
  declare domesticQuestionId: string;
  declare versionNumber: number;
  declare type: DomesticQuestionType;
  declare prompt: string;
  declare helpText: CreationOptional<string | null>;
  declare optionsConfig: CreationOptional<DomesticOptionsConfig | null>;
  declare validationConfig: CreationOptional<Record<string, unknown> | null>;
  declare purpose: CreationOptional<string | null>;
  declare consentPolicyId: CreationOptional<string | null>;
  declare contentHash: string;
  declare createdBy: CreationOptional<string | null>;
  declare publishedAt: CreationOptional<Date | null>;
  declare retiredAt: CreationOptional<Date | null>;
  declare createdAt: CreationOptional<Date>;
  declare updatedAt: CreationOptional<Date>;
}

export function initDomesticQuestionVersionModel(sequelize: Sequelize) {
  DomesticQuestionVersion.init(
    {
      id: {
        type: DataTypes.UUID,
        defaultValue: DataTypes.UUIDV4,
        primaryKey: true,
      },
      domesticQuestionId: { type: DataTypes.UUID, allowNull: false },
      versionNumber: { type: DataTypes.INTEGER, allowNull: false },
      type: {
        type: DataTypes.ENUM(
          "single_choice",
          "multi_choice",
          "yes_no",
          "rating",
          "number",
          "short_text"
        ),
        allowNull: false,
      },
      prompt: { type: DataTypes.TEXT, allowNull: false },
      helpText: { type: DataTypes.TEXT, allowNull: true },
      optionsConfig: {
        type: DataTypes.JSON,
        allowNull: true,
        get() {
          return parseJsonColumn<DomesticOptionsConfig>(
            this.getDataValue("optionsConfig")
          );
        },
      },
      validationConfig: {
        type: DataTypes.JSON,
        allowNull: true,
        get() {
          return parseJsonColumn<Record<string, unknown>>(
            this.getDataValue("validationConfig")
          );
        },
      },
      purpose: { type: DataTypes.STRING(500), allowNull: true },
      consentPolicyId: { type: DataTypes.UUID, allowNull: true },
      contentHash: { type: DataTypes.STRING(64), allowNull: false },
      createdBy: { type: DataTypes.UUID, allowNull: true },
      publishedAt: { type: DataTypes.DATE, allowNull: true },
      retiredAt: { type: DataTypes.DATE, allowNull: true },
      createdAt: DataTypes.DATE,
      updatedAt: DataTypes.DATE,
    },
    {
      sequelize,
      modelName: "DomesticQuestionVersion",
      tableName: "DomesticQuestionVersions",
    }
  );
  return DomesticQuestionVersion;
}
