import { DataTypes } from 'sequelize';
import sequelize from '../database.js';
import { encryptData, decryptData } from '../utils/encrypt.js';

const MyTischtennis = sequelize.define('MyTischtennis', {
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true,
    autoIncrement: true,
    allowNull: false
  },
  userId: {
    type: DataTypes.INTEGER,
    allowNull: false,
    unique: true,
    references: {
      model: 'user',
      key: 'id'
    },
    onDelete: 'CASCADE'
  },
  email: {
    type: DataTypes.STRING,
    allowNull: false,
    set(value) {
      const encryptedValue = encryptData(value);
      this.setDataValue('email', encryptedValue);
    },
    get() {
      const encryptedValue = this.getDataValue('email');
      return decryptData(encryptedValue);
    }
  },
  encryptedPassword: {
    type: DataTypes.TEXT('long'), // Use LONGTEXT for encrypted data
    allowNull: true,
    field: 'encrypted_password'
  },
  savePassword: {
    type: DataTypes.BOOLEAN,
    defaultValue: false,
    allowNull: false,
    field: 'save_password'
  },
  autoUpdateRatings: {
    type: DataTypes.BOOLEAN,
    defaultValue: false,
    allowNull: false,
    field: 'auto_update_ratings'
  },
  accessToken: {
    type: DataTypes.TEXT('long'), // Use LONGTEXT for encrypted data
    allowNull: true,
    field: 'access_token',
    set(value) {
      if (value === null || value === undefined) {
        this.setDataValue('accessToken', null);
      } else {
        const encryptedValue = encryptData(value);
        this.setDataValue('accessToken', encryptedValue);
      }
    },
    get() {
      const encryptedValue = this.getDataValue('accessToken');
      if (!encryptedValue) return null;
      return decryptData(encryptedValue);
    }
  },
  refreshToken: {
    type: DataTypes.TEXT('long'), // Use LONGTEXT for encrypted data
    allowNull: true,
    field: 'refresh_token',
    set(value) {
      if (value === null || value === undefined) {
        this.setDataValue('refreshToken', null);
      } else {
        const encryptedValue = encryptData(value);
        this.setDataValue('refreshToken', encryptedValue);
      }
    },
    get() {
      const encryptedValue = this.getDataValue('refreshToken');
      if (!encryptedValue) return null;
      return decryptData(encryptedValue);
    }
  },
  expiresAt: {
    type: DataTypes.BIGINT,
    allowNull: true,
    field: 'expires_at'
  },
  cookie: {
    type: DataTypes.TEXT('long'), // Use LONGTEXT for encrypted data
    allowNull: true,
    set(value) {
      if (value === null || value === undefined) {
        this.setDataValue('cookie', null);
      } else {
        const encryptedValue = encryptData(value);
        this.setDataValue('cookie', encryptedValue);
      }
    },
    get() {
      const encryptedValue = this.getDataValue('cookie');
      if (!encryptedValue) return null;
      return decryptData(encryptedValue);
    }
  },
  userData: {
    type: DataTypes.TEXT('long'), // Use LONGTEXT to support very long encrypted strings
    allowNull: true,
    field: 'user_data',
    set(value) {
      if (value === null || value === undefined) {
        this.setDataValue('userData', null);
      } else {
        const jsonString = typeof value === 'string' ? value : JSON.stringify(value);
        const encryptedValue = encryptData(jsonString);
        this.setDataValue('userData', encryptedValue);
      }
    },
    get() {
      const encryptedValue = this.getDataValue('userData');
      if (!encryptedValue) return null;
      try {
        const decryptedString = decryptData(encryptedValue);
        return JSON.parse(decryptedString);
      } catch (error) {
        console.error('Error decrypting/parsing userData:', error);
        return null;
      }
    }
  },
  clubId: {
    type: DataTypes.TEXT('long'), // Use LONGTEXT for encrypted data (can be longer than VARCHAR)
    allowNull: true,
    field: 'club_id',
    set(value) {
      if (value === null || value === undefined) {
        this.setDataValue('clubId', null);
      } else {
        const encryptedValue = encryptData(value);
        this.setDataValue('clubId', encryptedValue);
      }
    },
    get() {
      const encryptedValue = this.getDataValue('clubId');
      if (!encryptedValue) return null;
      return decryptData(encryptedValue);
    }
  },
  clubName: {
    type: DataTypes.TEXT('long'), // Use LONGTEXT for encrypted data (can be longer than VARCHAR)
    allowNull: true,
    field: 'club_name',
    set(value) {
      if (value === null || value === undefined) {
        this.setDataValue('clubName', null);
      } else {
        const encryptedValue = encryptData(value);
        this.setDataValue('clubName', encryptedValue);
      }
    },
    get() {
      const encryptedValue = this.getDataValue('clubName');
      if (!encryptedValue) return null;
      return decryptData(encryptedValue);
    }
  },
  fedNickname: {
    type: DataTypes.TEXT('long'), // Use LONGTEXT for encrypted data (can be longer than VARCHAR)
    allowNull: true,
    field: 'fed_nickname',
    set(value) {
      if (value === null || value === undefined) {
        this.setDataValue('fedNickname', null);
      } else {
        const encryptedValue = encryptData(value);
        this.setDataValue('fedNickname', encryptedValue);
      }
    },
    get() {
      const encryptedValue = this.getDataValue('fedNickname');
      if (!encryptedValue) return null;
      return decryptData(encryptedValue);
    }
  },
  lastLoginAttempt: {
    type: DataTypes.DATE,
    allowNull: true,
    field: 'last_login_attempt'
  },
  lastLoginSuccess: {
    type: DataTypes.DATE,
    allowNull: true,
    field: 'last_login_success'
  },
  lastUpdateRatings: {
    type: DataTypes.DATE,
    allowNull: true,
    field: 'last_update_ratings'
  },
  playwrightStorageState: {
    // Encrypted JSON blob: full Playwright browser storage state (cookies + localStorage).
    // Allows restoring a previous login session without a new CAPTCHA challenge.
    type: DataTypes.TEXT('long'),
    allowNull: true,
    field: 'playwright_storage_state',
    set(value) {
      if (value === null || value === undefined) {
        this.setDataValue('playwrightStorageState', null);
      } else {
        const jsonString = typeof value === 'string' ? value : JSON.stringify(value);
        this.setDataValue('playwrightStorageState', encryptData(jsonString));
      }
    },
    get() {
      const encrypted = this.getDataValue('playwrightStorageState');
      if (!encrypted) return null;
      try {
        return JSON.parse(decryptData(encrypted));
      } catch (_e) {
        return null;
      }
    }
  }
}, {
  underscored: true,
  tableName: 'my_tischtennis',
  timestamps: true,
  hooks: {
    beforeSave: async (instance) => {
      // Wenn savePassword false ist, password auf null setzen
      if (!instance.savePassword) {
        instance.encryptedPassword = null;
      }
    }
  }
});

// Virtuelle Felder für password handling
MyTischtennis.prototype.setPassword = function(password) {
  if (password && this.savePassword) {
    this.encryptedPassword = encryptData(password);
  } else {
    this.encryptedPassword = null;
  }
};

MyTischtennis.prototype.getPassword = function() {
  if (this.encryptedPassword) {
    try {
      return decryptData(this.encryptedPassword);
    } catch (error) {
      console.error('Error decrypting myTischtennis password:', error);
      return null;
    }
  }
  return null;
};

export default MyTischtennis;

