import {
  Column,
  CreateDateColumn,
  Entity,
  Index,
  JoinColumn,
  JoinTable,
  ManyToMany,
  ManyToOne,
  OneToMany,
  PrimaryGeneratedColumn,
  type Relation,
  Unique,
  UpdateDateColumn,
} from 'typeorm';
import { User } from '../../user/entities/user.entity';
import { Project } from '../../project/entities/project.entity';
import { ChecklistItem } from './checklist-item.entity';

// 업무 상태 (상태 머신: todo → prog → review → done/changes, changes → review)
export type TaskStatus = 'todo' | 'prog' | 'review' | 'done' | 'changes';

// 업무 엔티티 — 프로젝트에 종속, 프로젝트 내 순번(seq)으로 식별(#9)
@Entity('tasks')
@Unique(['project', 'seq'])
export class Task {
  // 내부 식별자 (UUID)
  @PrimaryGeneratedColumn('uuid')
  id!: string;

  // 프로젝트 내 표시 순번(#9) — 라우팅/표시 식별자. 프로젝트별로 1부터 증가
  @Index()
  @Column({ type: 'int' })
  seq!: number;

  // 소속 프로젝트 (프로젝트 삭제 시 함께 삭제)
  // Relation<> 래퍼: 엔티티 순환참조 회피.
  // FK 컬럼명을 snake_case 로 고정(집계 raw 쿼리의 task.project_id 와 일치)
  @ManyToOne(() => Project, { onDelete: 'CASCADE' })
  @JoinColumn({ name: 'project_id' })
  project!: Relation<Project>;

  // 업무 제목
  @Column()
  title!: string;

  // 본문 문단 배열(멘션은 @로 시작) — jsonb 로 보관
  @Column({ type: 'jsonb', default: () => "'[]'" })
  content!: string[];

  // 진행 상태
  @Column({ type: 'varchar', default: 'todo' })
  status!: TaskStatus;

  // 마감 기한(선택)
  @Column({ name: 'due_date', type: 'timestamptz', nullable: true })
  dueDate!: Date | null;

  // 지시자(업무 생성자) — 사용자 삭제 시에도 업무는 유지(SET NULL)
  @ManyToOne(() => User, { onDelete: 'SET NULL', nullable: true })
  issuer!: User | null;

  // 담당자 목록 (프로젝트 멤버만 지정 가능 — 서비스에서 검증)
  @ManyToMany(() => User)
  @JoinTable({
    name: 'task_assignees',
    joinColumn: { name: 'task_id', referencedColumnName: 'id' },
    inverseJoinColumn: { name: 'user_id', referencedColumnName: 'id' },
  })
  assignees!: User[];

  // 체크리스트 항목
  @OneToMany(() => ChecklistItem, (item) => item.task, { cascade: true })
  checklist!: Relation<ChecklistItem>[];

  // --- 승인 워크플로우(5단계) ---

  // 최근 승인 요청 메시지(담당자 → 지시자). 승인 대기(review) 상태에서 노출
  @Column({ name: 'approval_note', type: 'text', nullable: true })
  approvalNote!: string | null;

  // 승인을 요청한 사용자 (사용자 삭제 시 SET NULL)
  @ManyToOne(() => User, { onDelete: 'SET NULL', nullable: true })
  @JoinColumn({ name: 'approval_requested_by' })
  approvalRequestedBy!: User | null;

  // 승인 요청 시각
  @Column({
    name: 'approval_requested_at',
    type: 'timestamptz',
    nullable: true,
  })
  approvalRequestedAt!: Date | null;

  // 최근 수정 요청 메시지(지시자 → 담당자). 수정 요청(changes) 상태에서 노출
  @Column({ name: 'changes_note', type: 'text', nullable: true })
  changesNote!: string | null;

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

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