import {
  Sequelize,
  DataTypes,
  Model,
  InferAttributes,
  InferCreationAttributes,
  CreationOptional,
} from "sequelize";
import type {
  SurveyStatus,
  WelcomeScreenConfig,
  ThankYouScreenConfig,
  ThemeConfig,
} from "@/types";
import type { SurveyDisplayConfig } from "@/lib/utils/survey-display";
import { parseJsonColumn } from "@/lib/utils/parse-json-column";

export class Survey extends Model<
  InferAttributes<Survey>,
  InferCreationAttributes<Survey>
> {
  declare id: CreationOptional<string>;
  declare workspaceId: string;
  declare title: string;
  declare description: string | null;
  declare status: SurveyStatus;
  declare welcomeScreenConfig: WelcomeScreenConfig | null;
  declare thankYouScreenConfig: ThankYouScreenConfig | null;
  declare redirectUrl: string | null;
  declare themeConfig: ThemeConfig | null;
  declare displayConfig: SurveyDisplayConfig | null;
  declare createdBy: string | null;
  declare publishedAt: Date | null;
  declare closedAt: Date | null;
  declare createdAt: CreationOptional<Date>;
  declare updatedAt: CreationOptional<Date>;
}

export function initSurveyModel(sequelize: Sequelize) {
  Survey.init(
    {
      id: {
        type: DataTypes.UUID,
        defaultValue: DataTypes.UUIDV4,
        primaryKey: true,
      },
      workspaceId: { type: DataTypes.UUID, allowNull: false },
      title: { type: DataTypes.STRING(500), allowNull: false },
      description: { type: DataTypes.TEXT, allowNull: true },
      status: {
        type: DataTypes.ENUM("draft", "active", "closed"),
        allowNull: false,
        defaultValue: "draft",
      },
      welcomeScreenConfig: { type: DataTypes.JSON, allowNull: true },
      thankYouScreenConfig: {
        type: DataTypes.JSON,
        allowNull: true,
        get() {
          return parseJsonColumn<ThankYouScreenConfig>(
            this.getDataValue("thankYouScreenConfig")
          );
        },
        set(value: ThankYouScreenConfig | string | null) {
          this.setDataValue(
            "thankYouScreenConfig",
            typeof value === "string"
              ? parseJsonColumn<ThankYouScreenConfig>(value)
              : value
          );
        },
      },
      redirectUrl: { type: DataTypes.STRING(2048), allowNull: true },
      themeConfig: { type: DataTypes.JSON, allowNull: true },
      displayConfig: {
        type: DataTypes.JSON,
        allowNull: true,
        get() {
          return parseJsonColumn<SurveyDisplayConfig>(
            this.getDataValue("displayConfig")
          );
        },
        set(value: SurveyDisplayConfig | string | null) {
          this.setDataValue(
            "displayConfig",
            typeof value === "string"
              ? parseJsonColumn<SurveyDisplayConfig>(value)
              : value
          );
        },
      },
      createdBy: { type: DataTypes.UUID, allowNull: true },
      publishedAt: { type: DataTypes.DATE, allowNull: true },
      closedAt: { type: DataTypes.DATE, allowNull: true },
      createdAt: DataTypes.DATE,
      updatedAt: DataTypes.DATE,
    },
    { sequelize, modelName: "Survey", tableName: "Surveys" }
  );
  return Survey;
}
