import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
  Index,
  ManyToOne,
  JoinColumn,
} from 'typeorm';
import { Tenant } from './tenant.entity.js';
import { User } from './user.entity.js';
import { Role } from './role.entity.js';

@Entity({ schema: 'auth', name: 'oauth_providers' })
@Index('idx_oauth_providers_enabled', ['isEnabled'])
@Index('idx_oauth_providers_tenant', ['tenantId'])
@Index('idx_oauth_providers_code', ['code'])
export class OAuthProvider {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column({ type: 'uuid', nullable: true, name: 'tenant_id' })
  tenantId: string | null;

  @Column({ type: 'varchar', length: 50, nullable: false, unique: true })
  code: string;

  @Column({ type: 'varchar', length: 100, nullable: false })
  name: string;

  // Configuración OAuth2
  @Column({ type: 'varchar', length: 255, nullable: false, name: 'client_id' })
  clientId: string;

  @Column({ type: 'varchar', length: 500, nullable: true, name: 'client_secret' })
  clientSecret: string | null;

  // Endpoints OAuth2
  @Column({
    type: 'varchar',
    length: 500,
    nullable: false,
    name: 'authorization_endpoint',
  })
  authorizationEndpoint: string;

  @Column({
    type: 'varchar',
    length: 500,
    nullable: false,
    name: 'token_endpoint',
  })
  tokenEndpoint: string;

  @Column({
    type: 'varchar',
    length: 500,
    nullable: false,
    name: 'userinfo_endpoint',
  })
  userinfoEndpoint: string;

  @Column({ type: 'varchar', length: 500, nullable: true, name: 'jwks_uri' })
  jwksUri: string | null;

  // Scopes y parámetros
  @Column({
    type: 'varchar',
    length: 500,
    default: 'openid profile email',
    nullable: false,
  })
  scope: string;

  @Column({
    type: 'varchar',
    length: 50,
    default: 'code',
    nullable: false,
    name: 'response_type',
  })
  responseType: string;

  // PKCE Configuration
  @Column({
    type: 'boolean',
    default: true,
    nullable: false,
    name: 'pkce_enabled',
  })
  pkceEnabled: boolean;

  @Column({
    type: 'varchar',
    length: 10,
    default: 'S256',
    nullable: true,
    name: 'code_challenge_method',
  })
  codeChallengeMethod: string | null;

  // Mapeo de claims
  @Column({
    type: 'jsonb',
    nullable: false,
    name: 'claim_mapping',
    default: {
      sub: 'oauth_uid',
      email: 'email',
      name: 'name',
      picture: 'avatar_url',
    },
  })
  claimMapping: Record<string, any>;

  // UI
  @Column({ type: 'varchar', length: 100, nullable: true, name: 'icon_class' })
  iconClass: string | null;

  @Column({ type: 'varchar', length: 100, nullable: true, name: 'button_text' })
  buttonText: string | null;

  @Column({ type: 'varchar', length: 20, nullable: true, name: 'button_color' })
  buttonColor: string | null;

  @Column({
    type: 'integer',
    default: 10,
    nullable: false,
    name: 'display_order',
  })
  displayOrder: number;

  // Estado
  @Column({ type: 'boolean', default: false, nullable: false, name: 'is_enabled' })
  isEnabled: boolean;

  @Column({ type: 'boolean', default: true, nullable: false, name: 'is_visible' })
  isVisible: boolean;

  // Restricciones
  @Column({
    type: 'text',
    array: true,
    nullable: true,
    name: 'allowed_domains',
  })
  allowedDomains: string[] | null;

  @Column({
    type: 'boolean',
    default: false,
    nullable: false,
    name: 'auto_create_users',
  })
  autoCreateUsers: boolean;

  @Column({ type: 'uuid', nullable: true, name: 'default_role_id' })
  defaultRoleId: string | null;

  // Relaciones
  @ManyToOne(() => Tenant, { onDelete: 'CASCADE', nullable: true })
  @JoinColumn({ name: 'tenant_id' })
  tenant: Tenant | null;

  @ManyToOne(() => Role, { nullable: true })
  @JoinColumn({ name: 'default_role_id' })
  defaultRole: Role | null;

  @ManyToOne(() => User, { nullable: true })
  @JoinColumn({ name: 'created_by' })
  createdByUser: User | null;

  @ManyToOne(() => User, { nullable: true })
  @JoinColumn({ name: 'updated_by' })
  updatedByUser: User | null;

  // Auditoría
  @CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
  createdAt: Date;

  @Column({ type: 'uuid', nullable: true, name: 'created_by' })
  createdBy: string | null;

  @UpdateDateColumn({ name: 'updated_at', type: 'timestamptz' })
  updatedAt: Date;

  @Column({ type: 'uuid', nullable: true, name: 'updated_by' })
  updatedBy: string | null;
}
