/**
 * CostCenter Entity
 * Centros de costo jerárquicos para imputación de gastos
 *
 * @module Admin
 * @table admin.cost_centers
 */

import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
  ManyToOne,
  OneToMany,
  JoinColumn,
  Index,
  Tree,
  TreeChildren,
  TreeParent,
} from 'typeorm';
import { Tenant } from '../../core/entities/tenant.entity';
import { User } from '../../core/entities/user.entity';

export type CostCenterType = 'direct' | 'indirect' | 'shared_services' | 'overhead';

export type CostCenterLevel = 'company' | 'project' | 'phase' | 'front' | 'activity';

@Entity({ schema: 'admin', name: 'cost_centers' })
@Tree('closure-table')
@Index(['tenantId', 'code'], { unique: true })
@Index(['tenantId'])
@Index(['parentId'])
@Index(['fraccionamientoId'])
@Index(['costCenterType'])
@Index(['level'])
@Index(['isActive'])
export class CostCenter {
  @PrimaryGeneratedColumn('uuid')
  id: string;

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

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

  @Column({ type: 'varchar', length: 200 })
  name: string;

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

  @Column({
    name: 'cost_center_type',
    type: 'varchar',
    length: 30,
    default: 'direct',
  })
  costCenterType: CostCenterType;

  @Column({
    type: 'varchar',
    length: 20,
    default: 'activity',
  })
  level: CostCenterLevel;

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

  @Column({
    name: 'fraccionamiento_id',
    type: 'uuid',
    nullable: true,
    comment: 'Project this cost center belongs to (null for company level)',
  })
  fraccionamientoId: string | null;

  @Column({
    name: 'responsible_id',
    type: 'uuid',
    nullable: true,
    comment: 'User responsible for this cost center',
  })
  responsibleId: string | null;

  @Column({
    type: 'decimal',
    precision: 16,
    scale: 2,
    default: 0,
    comment: 'Annual budget for this cost center',
  })
  budget: number;

  @Column({
    name: 'budget_consumed',
    type: 'decimal',
    precision: 16,
    scale: 2,
    default: 0,
    comment: 'Amount consumed from budget',
  })
  budgetConsumed: number;

  @Column({
    name: 'distribution_percentage',
    type: 'decimal',
    precision: 5,
    scale: 2,
    nullable: true,
    comment: 'Percentage for indirect cost distribution',
  })
  distributionPercentage: number | null;

  @Column({
    name: 'distribution_base',
    type: 'varchar',
    length: 50,
    nullable: true,
    comment: 'Base for distribution: direct_cost, headcount, area, etc.',
  })
  distributionBase: string | null;

  @Column({
    name: 'accounting_code',
    type: 'varchar',
    length: 50,
    nullable: true,
    comment: 'Code for accounting system integration',
  })
  accountingCode: string | null;

  @Column({
    name: 'is_billable',
    type: 'boolean',
    default: false,
    comment: 'Can be billed to client',
  })
  isBillable: boolean;

  @Column({
    name: 'is_active',
    type: 'boolean',
    default: true,
  })
  isActive: boolean;

  @Column({
    name: 'sort_order',
    type: 'integer',
    default: 0,
  })
  sortOrder: number;

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

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

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

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

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

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

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

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

  @TreeParent()
  @ManyToOne(() => CostCenter, (cc) => cc.children)
  @JoinColumn({ name: 'parent_id' })
  parent: CostCenter | null;

  @TreeChildren()
  @OneToMany(() => CostCenter, (cc) => cc.parent)
  children: CostCenter[];

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

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