import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  Index,
  CreateDateColumn,
  UpdateDateColumn,
} from 'typeorm';
import { IdempotencyStatusEnum } from '../enum/idempotency-status.enum';

// One row per (idempotency_key, endpoint, user_id) triple — the same client-generated key can
// be reused across different endpoints, or (in principle) by different users, without colliding.
// See IdempotencyRepository for the atomic claim/replay logic that relies on this constraint.
@Entity('idempotency_key')
@Index('uq_idempotency_key_endpoint_user', ['idempotencyKey', 'endpoint', 'userId'], { unique: true })
export class IdempotencyKey {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ name: 'idempotency_key', type: 'varchar', length: 255 })
  idempotencyKey: string;

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

  @Column({ name: 'request_hash', type: 'varchar', length: 64 })
  requestHash: string;

  @Column({
    name: 'status',
    type: 'enum',
    enum: IdempotencyStatusEnum,
    default: IdempotencyStatusEnum.PENDING,
  })
  status: IdempotencyStatusEnum;

  @Column({ name: 'response_data', type: 'jsonb', nullable: true })
  responseData: object | null;

  @Column({ name: 'user_id', type: 'int', nullable: true })
  userId: number | null;

  // Starts at 1 on the initial claim; incremented on every later request that matches
  // the same (idempotency_key, endpoint, user_id) — replay, conflict, or reclaim alike.
  @Column({ name: 'hit_count', type: 'int', default: 1 })
  hitCount: number;

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

  @UpdateDateColumn({ name: 'updated_at', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP', onUpdate: 'CURRENT_TIMESTAMP' })
  updatedAt: Date;

  constructor(partial: Partial<IdempotencyKey>) {
    Object.assign(this, partial);
  }
}
