import {
  Column,
  CreateDateColumn,
  Entity,
  Index,
  JoinColumn,
  ManyToOne,
  PrimaryGeneratedColumn,
  type Relation,
  UpdateDateColumn,
} from 'typeorm';
import { User } from '../../user/entities/user.entity';
import { DriveFolder } from './drive-folder.entity';
import { numericColumnTransformer } from '../../../common/database/numeric-column.transformer';
import type { AttachmentKind } from '../../task/entities/attachment.entity';

// 드라이브 파일 업로드 상태
// pending: presign 발급됨(아직 실제 업로드/검증 전) / active: 업로드 완료·검증 통과
export type DriveFileStatus = 'pending' | 'active';

// 드라이브 파일 — 실제 바이너리는 오브젝트 스토리지에 저장하고 메타데이터만 보관.
// 업로드는 presigned URL 직접 전송 후 complete 로 확정한다.
@Entity('drive_files')
export class DriveFile {
  @PrimaryGeneratedColumn('uuid')
  id!: string;

  // 소유자 (사용자 삭제 시 파일 메타도 함께 삭제 — 객체 정리는 서비스가 담당)
  @Index()
  @ManyToOne(() => User, { onDelete: 'CASCADE' })
  @JoinColumn({ name: 'owner_id' })
  owner!: User;

  // 소속 폴더 (null = 드라이브 루트). 폴더 삭제 시 파일 메타도 함께 삭제(CASCADE).
  @Index()
  @ManyToOne(() => DriveFolder, { onDelete: 'CASCADE', nullable: true })
  @JoinColumn({ name: 'folder_id' })
  folder!: Relation<DriveFolder> | null;

  // 원본 파일명(다운로드 시 표시)
  @Column()
  name!: string;

  // 저장 버킷 — 추후 버킷 이전 대비해 메타에 함께 보관
  @Column()
  bucket!: string;

  // 버킷 내 객체 키(고유). 예: development/drive/{userId}/{uuid}-name.pdf
  @Index({ unique: true })
  @Column({ name: 'object_key' })
  objectKey!: string;

  // 파일 크기(바이트) — 대용량 대비 bigint(문자열) → number 변환
  @Column({ type: 'bigint', transformer: numericColumnTransformer })
  size!: number;

  // MIME 타입
  @Column()
  mime!: string;

  // 아이콘 종류(MIME/확장자에서 파생) — 업무/프로젝트 첨부와 동일 분류 재사용
  @Column({ type: 'varchar' })
  kind!: AttachmentKind;

  // 업로드 상태 — pending 은 미완료(목록/다운로드 비노출), 정리 크론 대상
  @Index()
  @Column({ type: 'varchar', default: 'pending' })
  status!: DriveFileStatus;

  @CreateDateColumn({ name: 'created_at' })
  createdAt!: Date;

  @UpdateDateColumn({ name: 'updated_at' })
  updatedAt!: Date;
}
