/**
 * Document Entity - Registro Principal de Documentos
 * Sistema de gestion documental.
 *
 * @module Documents (MAE-016)
 */

import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
  ManyToOne,
  OneToMany,
  JoinColumn,
  Index,
} from 'typeorm';
import { DocumentCategory, AccessLevel } from './document-category.entity';
import { DocumentVersion } from './document-version.entity';
import { Annotation } from './annotation.entity';

export type DocumentType =
  | 'plan'
  | 'specification'
  | 'contract'
  | 'permit'
  | 'report'
  | 'photograph'
  | 'drawing'
  | 'manual'
  | 'procedure'
  | 'form'
  | 'correspondence'
  | 'invoice'
  | 'estimate'
  | 'other';

export type DocumentStatus =
  | 'draft'
  | 'pending_review'
  | 'in_review'
  | 'approved'
  | 'rejected'
  | 'obsolete'
  | 'archived';

@Entity('documents', { schema: 'documents' })
@Index(['tenantId', 'documentCode'], { unique: true })
@Index(['tenantId', 'categoryId'])
@Index(['tenantId', 'documentType'])
@Index(['tenantId', 'status'])
@Index(['tenantId', 'projectId'])
export class Document {
  @PrimaryGeneratedColumn('uuid')
  id!: string;

  @Column({ name: 'tenant_id', type: 'uuid' })
  @Index()
  tenantId!: string;

  // Identificacion
  @Column({ name: 'document_code', length: 100 })
  documentCode!: string;

  @Column({ length: 500 })
  title!: string;

  @Column({ type: 'text', nullable: true })
  description?: string;

  // Clasificacion
  @Column({ name: 'category_id', type: 'uuid', nullable: true })
  categoryId?: string;

  @ManyToOne(() => DocumentCategory, { nullable: true })
  @JoinColumn({ name: 'category_id' })
  category?: DocumentCategory;

  @Column({
    name: 'document_type',
    type: 'enum',
    enum: ['plan', 'specification', 'contract', 'permit', 'report', 'photograph', 'drawing', 'manual', 'procedure', 'form', 'correspondence', 'invoice', 'estimate', 'other'],
    enumName: 'document_type',
  })
  documentType!: DocumentType;

  @Column({
    type: 'enum',
    enum: ['draft', 'pending_review', 'in_review', 'approved', 'rejected', 'obsolete', 'archived'],
    enumName: 'document_status',
    default: 'draft',
  })
  status!: DocumentStatus;

  @Column({
    name: 'access_level',
    type: 'enum',
    enum: ['public', 'internal', 'confidential', 'restricted'],
    enumName: 'access_level',
    default: 'internal',
  })
  accessLevel!: AccessLevel;

  // Version actual
  @Column({ name: 'current_version_id', type: 'uuid', nullable: true })
  currentVersionId?: string;

  @Column({ name: 'current_version_number', length: 20, default: '1.0' })
  currentVersionNumber!: string;

  // Proyecto/Contexto
  @Column({ name: 'project_id', type: 'uuid', nullable: true })
  projectId?: string;

  @Column({ name: 'project_code', length: 50, nullable: true })
  projectCode?: string;

  @Column({ name: 'project_name', length: 255, nullable: true })
  projectName?: string;

  // Metadatos del documento
  @Column({ length: 255, nullable: true })
  author?: string;

  @Column({ type: 'varchar', array: true, nullable: true })
  keywords?: string[];

  @Column({ type: 'varchar', array: true, nullable: true })
  tags?: string[];

  // Fechas importantes
  @Column({ name: 'document_date', type: 'date', nullable: true })
  documentDate?: Date;

  @Column({ name: 'effective_date', type: 'date', nullable: true })
  effectiveDate?: Date;

  @Column({ name: 'expiry_date', type: 'date', nullable: true })
  expiryDate?: Date;

  @Column({ name: 'review_date', type: 'date', nullable: true })
  reviewDate?: Date;

  // Origen
  @Column({ length: 100, nullable: true })
  source?: string;

  @Column({ name: 'external_reference', length: 255, nullable: true })
  externalReference?: string;

  @Column({ name: 'original_filename', length: 500, nullable: true })
  originalFilename?: string;

  // Relaciones de documentos
  @Column({ name: 'parent_document_id', type: 'uuid', nullable: true })
  parentDocumentId?: string;

  @ManyToOne(() => Document, { nullable: true })
  @JoinColumn({ name: 'parent_document_id' })
  parentDocument?: Document;

  @Column({ name: 'related_documents', type: 'uuid', array: true, nullable: true })
  relatedDocuments?: string[];

  // Flujo de aprobacion
  @Column({ name: 'requires_approval', type: 'boolean', default: false })
  requiresApproval!: boolean;

  @Column({ name: 'current_workflow_id', type: 'uuid', nullable: true })
  currentWorkflowId?: string;

  @Column({ name: 'approved_by_id', type: 'uuid', nullable: true })
  approvedById?: string;

  @Column({ name: 'approved_at', type: 'timestamptz', nullable: true })
  approvedAt?: Date;

  // Estadisticas
  @Column({ name: 'view_count', type: 'int', default: 0 })
  viewCount!: number;

  @Column({ name: 'download_count', type: 'int', default: 0 })
  downloadCount!: number;

  @Column({ name: 'last_accessed_at', type: 'timestamptz', nullable: true })
  lastAccessedAt?: Date;

  // Flags
  @Column({ name: 'is_template', type: 'boolean', default: false })
  isTemplate!: boolean;

  @Column({ name: 'is_locked', type: 'boolean', default: false })
  isLocked!: boolean;

  @Column({ name: 'locked_by_id', type: 'uuid', nullable: true })
  lockedById?: string;

  @Column({ name: 'locked_at', type: 'timestamptz', nullable: true })
  lockedAt?: Date;

  // Notas y metadatos
  @Column({ type: 'text', nullable: true })
  notes?: string;

  @Column({ name: 'custom_fields', type: 'jsonb', nullable: true })
  customFields?: Record<string, any>;

  @Column({ type: 'jsonb', nullable: true })
  metadata?: Record<string, any>;

  // Relaciones
  @OneToMany(() => DocumentVersion, (version) => version.document)
  versions?: DocumentVersion[];

  @OneToMany(() => Annotation, (annotation) => annotation.document)
  annotations?: Annotation[];

  // Auditoria
  @Column({ name: 'created_by', type: 'uuid', nullable: true })
  createdBy?: string;

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

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

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

  @Column({ name: 'deleted_at', type: 'timestamptz', nullable: true })
  deletedAt?: Date;
}
