import { Exclude, Expose } from 'class-transformer';
import { Column } from 'typeorm';
import { CoreEntity } from './core-entity';
import { AppRole, Role } from '../role.entity';
import { Transform } from '@nestjs/class-transformer';
import {
  IsArray,
  IsBoolean,
  IsOptional,
  IsPhoneNumber,
  IsString,
  MinLength,
  ValidateIf,
} from 'class-validator';
import { SystemLang } from '@/system/lang/system.lang';
import { IsUniqueInDatabase } from '@/system/validators/decorators/is-unique-in-database.decorator';
import { User } from '../user.entity';
import { IsExistInDatabase } from '@/system/validators/decorators/is-exist-in-database';
import { IsValidBase64Image } from '@/system/validators/decorators/is-valid-base64-image';

export default class Auth extends CoreEntity {
  public static table_name: string = '';

  @Column({ type: 'varchar', unique: true })
  email: string;

  @Column({ type: 'varchar', unique: true })
  username: string;

  @Column({ type: 'varchar', default: null, nullable: true })
  @IsString({
    message: SystemLang.getCustomText({
      vi: 'Tên không được để trống',
      en: 'First name cannot be empty',
    }),
  })
  @IsOptional()
  first_name: string;

  @Column({ type: 'varchar', default: null, nullable: true })
  @IsString({
    message: SystemLang.getCustomText({
      vi: 'Họ không được để trống',
      en: 'Last name cannot be empty',
    }),
  })
  @IsOptional()
  last_name: string;

  @Column({ type: 'varchar' })
  @Exclude()
  @IsOptional()
  @IsString({
    message: SystemLang.getCustomText({
      vi: 'Mật khẩu không được để trống',
      en: 'Password cannot be empty',
    }),
  })
  @MinLength(6, {
    message: SystemLang.getCustomText({
      en: 'Password must be at least 6 characters',
      vi: 'Mật khẩu phải có ít nhất 6 ký tự',
    }),
  })
  password: string;

  @Column({ type: 'varchar', nullable: true, unique: true, default: null })
  @IsPhoneNumber('VN', {
    message: SystemLang.getCustomText({
      en: 'Phone must be a valid Vietnamese phone number',
      vi: 'Số điện thoại phải là số hợp lệ tại Việt Nam',
    }),
  })
  @IsUniqueInDatabase(
    User,
    'phone',
    {
      allowNull: true,
    },
    {
      message: SystemLang.getCustomText({
        en: 'Phone number already exists in the system',
        vi: 'Số điện thoại đã tồn tại trong hệ thống',
      }),
    },
  )
  @IsOptional()
  phone: string | null;

  @Column({ type: 'varchar', nullable: true, default: null })
  @Transform(({ obj, value }) => {
    if (!value) return null;

    const username = obj.username;
    const path = `medias/avatars/${username}/${value}`;
    const env = process.env.ENV || 'production';
    const prefix = process.env.PREFIX_VERSION || '/api';
    const port = process.env.APP_PORT || '4000';

    if (env === 'dev') {
      return `http://localhost:${port}${prefix}/${path}`;
    }

    return path;
  })
  @IsValidBase64Image(
    {
      mimeTypes: ['image/jpeg', 'image/png'],
      maxSizeInBytes: 2 * 1024 * 1024, // 2MB
      maxWidth: 1024,
      maxHeight: 1024,
      allowNull: true,
    },
    {
      message: SystemLang.getCustomText({
        en: 'Avatar must be an image (JPG, PNG), size < 2MB, max dimensions 1024x1024',
        vi: 'Avatar phải là ảnh (JPG, PNG), dung lượng < 2MB, kích thước tối đa 1024x1024',
      }),
    },
  )
  @IsOptional()
  avatar: string | null;

  @Column({ type: 'boolean', nullable: false, default: false })
  @IsBoolean({
    message: SystemLang.getCustomText({
      en: 'is_login_enabled must be a boolean value',
      vi: 'is_login_enabled phải là kiểu boolean',
    }),
  })
  @IsOptional()
  is_login_enabled: boolean;

  @Column({ type: 'boolean', nullable: false, default: true })
  @IsBoolean({
    message: SystemLang.getCustomText({
      en: 'Active must be a boolean value',
      vi: 'Trạng thái hoạt động phải là kiểu boolean',
    }),
  })
  @IsOptional()
  active: boolean;

  @IsExistInDatabase(
    Role,
    'id',
    {
      except: (currentRow: Role) => {
        if (!currentRow) return false;

        return currentRow.role_key === AppRole.ROOT;
      },
    },
    {
      each: true,
      message: SystemLang.getCustomText({
        en: 'One or more roles do not exist or are not allowed to be modified (e.g. ROOT role).',
        vi: 'Một hoặc nhiều vai trò không tồn tại hoặc không được phép chỉnh sửa (ví dụ: vai trò ROOT).',
      }),
    },
  )
  @IsOptional()
  @IsArray()
  @Expose()
  roles: Role[] = [];

  getFullname() {
    return `${this.first_name} ${this.last_name}`;
  }
}
