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

/** Append-only — corrections are new rows with a higher `revision`. */
export class DomesticAnswer extends Model<
  InferAttributes<DomesticAnswer>,
  InferCreationAttributes<DomesticAnswer>
> {
  declare id: CreationOptional<string>;
  declare participantProfileId: string;
  declare domesticQuestionId: string;
  declare questionVersionId: string;
  declare queueItemId: CreationOptional<string | null>;
  declare value: unknown;
  declare revision: CreationOptional<number>;
  declare consentRecordId: CreationOptional<string | null>;
  declare source: CreationOptional<DomesticAnswerSource>;
  declare idempotencyKey: string;
  declare appliedEdgeIds: CreationOptional<string[] | null>;
  declare answeredAt: Date;
  declare createdAt: CreationOptional<Date>;
  declare updatedAt: CreationOptional<Date>;
}

export function initDomesticAnswerModel(sequelize: Sequelize) {
  DomesticAnswer.init(
    {
      id: {
        type: DataTypes.UUID,
        defaultValue: DataTypes.UUIDV4,
        primaryKey: true,
      },
      participantProfileId: { type: DataTypes.UUID, allowNull: false },
      domesticQuestionId: { type: DataTypes.UUID, allowNull: false },
      questionVersionId: { type: DataTypes.UUID, allowNull: false },
      queueItemId: { type: DataTypes.UUID, allowNull: true },
      value: {
        type: DataTypes.JSON,
        allowNull: true,
        get() {
          return parseJsonValue(this.getDataValue("value"));
        },
      },
      revision: { type: DataTypes.INTEGER, allowNull: false, defaultValue: 1 },
      consentRecordId: { type: DataTypes.UUID, allowNull: true },
      source: {
        type: DataTypes.ENUM("feed", "profile", "import"),
        allowNull: false,
        defaultValue: "feed",
      },
      idempotencyKey: {
        type: DataTypes.STRING(100),
        allowNull: false,
        unique: true,
      },
      appliedEdgeIds: {
        type: DataTypes.JSON,
        allowNull: true,
        get() {
          const v = parseJsonValue(this.getDataValue("appliedEdgeIds"));
          return Array.isArray(v) ? (v as string[]) : null;
        },
      },
      answeredAt: { type: DataTypes.DATE, allowNull: false },
      createdAt: DataTypes.DATE,
      updatedAt: DataTypes.DATE,
    },
    { sequelize, modelName: "DomesticAnswer", tableName: "DomesticAnswers" }
  );
  return DomesticAnswer;
}
