/**
 * ReportExecution Entity
 * Historial de ejecuciones de reportes
 *
 * @module Reports
 * @table reports.report_executions
 */

import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  ManyToOne,
  JoinColumn,
  Index,
} from 'typeorm';
import { Tenant } from '../../core/entities/tenant.entity';
import { User } from '../../core/entities/user.entity';
import { Report, ReportFormat } from './report.entity';

export type ExecutionStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';

@Entity({ schema: 'reports', name: 'report_executions' })
@Index(['tenantId'])
@Index(['reportId'])
@Index(['status'])
@Index(['executedAt'])
@Index(['executedById'])
export class ReportExecution {
  @PrimaryGeneratedColumn('uuid')
  id: string;

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

  @Column({ name: 'report_id', type: 'uuid' })
  reportId: string;

  @Column({
    type: 'varchar',
    length: 20,
    default: 'pending',
  })
  status: ExecutionStatus;

  @Column({
    type: 'varchar',
    length: 20,
  })
  format: ReportFormat;

  @Column({
    type: 'jsonb',
    nullable: true,
    comment: 'Parameters used for this execution',
  })
  parameters: Record<string, any> | null;

  @Column({
    type: 'jsonb',
    nullable: true,
    comment: 'Filters applied',
  })
  filters: Record<string, any> | null;

  @Column({
    name: 'started_at',
    type: 'timestamptz',
    nullable: true,
  })
  startedAt: Date | null;

  @Column({
    name: 'completed_at',
    type: 'timestamptz',
    nullable: true,
  })
  completedAt: Date | null;

  @Column({
    name: 'duration_ms',
    type: 'integer',
    nullable: true,
    comment: 'Execution duration in milliseconds',
  })
  durationMs: number | null;

  @Column({
    name: 'row_count',
    type: 'integer',
    nullable: true,
  })
  rowCount: number | null;

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

  @Column({
    name: 'file_size',
    type: 'integer',
    nullable: true,
    comment: 'File size in bytes',
  })
  fileSize: number | null;

  @Column({
    name: 'file_url',
    type: 'varchar',
    length: 1000,
    nullable: true,
    comment: 'Presigned URL or download URL',
  })
  fileUrl: string | null;

  @Column({
    name: 'url_expires_at',
    type: 'timestamptz',
    nullable: true,
  })
  urlExpiresAt: Date | null;

  @Column({
    name: 'error_message',
    type: 'text',
    nullable: true,
  })
  errorMessage: string | null;

  @Column({
    name: 'error_stack',
    type: 'text',
    nullable: true,
  })
  errorStack: string | null;

  @Column({
    name: 'is_scheduled',
    type: 'boolean',
    default: false,
    comment: 'Was this a scheduled execution?',
  })
  isScheduled: boolean;

  @Column({
    name: 'distributed_to',
    type: 'varchar',
    array: true,
    nullable: true,
    comment: 'Email addresses report was sent to',
  })
  distributedTo: string[] | null;

  @Column({
    name: 'distributed_at',
    type: 'timestamptz',
    nullable: true,
  })
  distributedAt: Date | null;

  @Column({
    name: 'executed_at',
    type: 'timestamptz',
    default: () => 'CURRENT_TIMESTAMP',
  })
  executedAt: Date;

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

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

  // Relations
  @ManyToOne(() => Tenant)
  @JoinColumn({ name: 'tenant_id' })
  tenant: Tenant;

  @ManyToOne(() => Report)
  @JoinColumn({ name: 'report_id' })
  report: Report;

  @ManyToOne(() => User)
  @JoinColumn({ name: 'executed_by' })
  executedBy: User | null;
}
