import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
  Index,
  ManyToOne,
  OneToMany,
  JoinColumn,
} from 'typeorm';
import { Department } from './department.entity';
import { JobPosition } from './job-position.entity';
import { Contract } from './contract.entity';
import { Leave } from './leave.entity';
import { LeaveAllocation } from './leave-allocation.entity';

/**
 * Employee Status Enum
 */
export type EmployeeStatus = 'active' | 'inactive' | 'on_leave' | 'terminated';

/**
 * Employee Entity (schema: hr.employees)
 *
 * Core employee information including personal data, organization assignment,
 * and employment details. Supports self-referential manager relationship.
 *
 * Relations:
 * - user_id: References auth.users (optional - employee may not have system access)
 * - partner_id: References partners.partners (optional - employee as business contact)
 * - department_id: Current department assignment
 * - job_position_id: Current job position
 * - manager_id: Direct manager (self-reference)
 *
 * RLS Policy: tenant_id = current_setting('app.current_tenant_id')
 */
@Entity({ name: 'employees', schema: 'hr' })
@Index(['tenantId', 'employeeNumber'], { unique: true })
export class Employee {
  @PrimaryGeneratedColumn('uuid')
  id: string;

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

  @Index()
  @Column({ name: 'company_id', type: 'uuid' })
  companyId: string;

  @Column({ name: 'employee_number', type: 'varchar', length: 50 })
  employeeNumber: string;

  @Column({ name: 'first_name', type: 'varchar', length: 100 })
  firstName: string;

  @Column({ name: 'last_name', type: 'varchar', length: 100 })
  lastName: string;

  /**
   * Generated column in PostgreSQL: first_name || ' ' || last_name
   * Mark as insert: false, update: false since it's computed by DB
   */
  @Index()
  @Column({
    name: 'full_name',
    type: 'varchar',
    length: 255,
    insert: false,
    update: false,
    nullable: true,
  })
  fullName: string;

  @Index()
  @Column({ name: 'user_id', type: 'uuid', nullable: true })
  userId: string | null;

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

  @Index()
  @Column({ name: 'department_id', type: 'uuid', nullable: true })
  departmentId: string | null;

  @ManyToOne(() => Department, (department) => department.employees, {
    onDelete: 'SET NULL',
  })
  @JoinColumn({ name: 'department_id' })
  department: Department | null;

  @Index()
  @Column({ name: 'job_position_id', type: 'uuid', nullable: true })
  jobPositionId: string | null;

  @ManyToOne(() => JobPosition, (position) => position.employees, {
    onDelete: 'SET NULL',
  })
  @JoinColumn({ name: 'job_position_id' })
  jobPosition: JobPosition | null;

  @Index()
  @Column({ name: 'manager_id', type: 'uuid', nullable: true })
  managerId: string | null;

  @ManyToOne(() => Employee, (employee) => employee.subordinates, {
    onDelete: 'SET NULL',
  })
  @JoinColumn({ name: 'manager_id' })
  manager: Employee | null;

  @OneToMany(() => Employee, (employee) => employee.manager)
  subordinates: Employee[];

  // Work contact
  @Column({ name: 'work_email', type: 'varchar', length: 255, nullable: true })
  workEmail: string | null;

  @Column({ name: 'work_phone', type: 'varchar', length: 50, nullable: true })
  workPhone: string | null;

  @Column({ name: 'work_mobile', type: 'varchar', length: 50, nullable: true })
  workMobile: string | null;

  @Column({ name: 'work_location', type: 'varchar', length: 255, nullable: true })
  workLocation: string | null;

  // Personal data
  @Column({ name: 'personal_email', type: 'varchar', length: 255, nullable: true })
  personalEmail: string | null;

  @Column({ name: 'personal_phone', type: 'varchar', length: 50, nullable: true })
  personalPhone: string | null;

  @Column({ name: 'birth_date', type: 'date', nullable: true })
  birthDate: Date | null;

  @Column({ name: 'gender', type: 'varchar', length: 20, nullable: true })
  gender: string | null;

  @Column({ name: 'marital_status', type: 'varchar', length: 20, nullable: true })
  maritalStatus: string | null;

  // Official identification
  @Column({ name: 'identification_type', type: 'varchar', length: 50, nullable: true })
  identificationType: string | null;

  @Column({ name: 'identification_number', type: 'varchar', length: 100, nullable: true })
  identificationNumber: string | null;

  @Column({ name: 'tax_id', type: 'varchar', length: 50, nullable: true })
  taxId: string | null;

  @Column({ name: 'social_security_number', type: 'varchar', length: 50, nullable: true })
  socialSecurityNumber: string | null;

  // Address
  @Column({ name: 'street', type: 'varchar', length: 255, nullable: true })
  street: string | null;

  @Column({ name: 'city', type: 'varchar', length: 100, nullable: true })
  city: string | null;

  @Column({ name: 'state', type: 'varchar', length: 100, nullable: true })
  state: string | null;

  @Column({ name: 'postal_code', type: 'varchar', length: 20, nullable: true })
  postalCode: string | null;

  @Column({ name: 'country', type: 'varchar', length: 100, nullable: true })
  country: string | null;

  // Employment
  @Column({ name: 'hire_date', type: 'date' })
  hireDate: Date;

  @Column({ name: 'termination_date', type: 'date', nullable: true })
  terminationDate: Date | null;

  @Index()
  @Column({
    name: 'status',
    type: 'enum',
    enum: ['active', 'inactive', 'on_leave', 'terminated'],
    enumName: 'hr_employee_status',
    default: 'active',
  })
  status: EmployeeStatus;

  // Emergency contact
  @Column({ name: 'emergency_contact_name', type: 'varchar', length: 255, nullable: true })
  emergencyContactName: string | null;

  @Column({ name: 'emergency_contact_phone', type: 'varchar', length: 50, nullable: true })
  emergencyContactPhone: string | null;

  @Column({ name: 'emergency_contact_relationship', type: 'varchar', length: 50, nullable: true })
  emergencyContactRelationship: string | null;

  // Metadata
  @Column({ name: 'notes', type: 'text', nullable: true })
  notes: string | null;

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

  // Relations
  @OneToMany(() => Contract, (contract) => contract.employee)
  contracts: Contract[];

  @OneToMany(() => Leave, (leave) => leave.employee)
  leaves: Leave[];

  @OneToMany(() => LeaveAllocation, (allocation) => allocation.employee)
  leaveAllocations: LeaveAllocation[];

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

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