import { BaseEntity } from '@edr/api-common';
import { Column, Entity, Index, JoinColumn, ManyToOne } from 'typeorm';

import { Rate } from './rate.entity';

export type RateChangeStatus = 'PENDING' | 'APPROVED' | 'REJECTED';

/**
 * One proposed edit to a LIVE rate, awaiting approval.
 *
 * A LIVE rate is what pricing actually charges, so it is never mutated in
 * place: the edit is filed here and the live row keeps its old value until an
 * approver applies it. `payload` holds only the changed fields (an
 * UpdateRateDto patch), `rateId` the rate being repriced.
 *
 * DRAFT rates are not covered — nothing prices off a draft, so those still
 * edit directly and reach LIVE through the existing submit/approve flow.
 */
@Entity({ schema: 'freight', name: 'rate_change_requests' })
@Index(['status'])
export class RateChangeRequest extends BaseEntity {
  @Column({ name: 'rate_id', type: 'uuid' })
  rateId!: string;

  @ManyToOne(() => Rate, { nullable: false })
  @JoinColumn({ name: 'rate_id' })
  rate?: Rate | null;

  /** Proposed field changes — an UpdateRateDto patch, changed keys only. */
  @Column({ name: 'payload', type: 'jsonb' })
  payload!: Record<string, unknown>;

  /**
   * The rate's values at submit time, for the approver's before→after diff.
   * Snapshotted because the live row can move on between submit and decision.
   */
  @Column({ name: 'previous_values', type: 'jsonb' })
  previousValues!: Record<string, unknown>;

  @Column({ name: 'status', type: 'varchar', length: 10, default: 'PENDING' })
  status!: RateChangeStatus;

  @Column({ name: 'requested_by_user_id', type: 'uuid', nullable: true })
  requestedByUserId?: string | null;

  @Column({ name: 'decided_by_user_id', type: 'uuid', nullable: true })
  decidedByUserId?: string | null;

  @Column({ name: 'decided_at', type: 'timestamptz', nullable: true })
  decidedAt?: Date | null;

  @Column({ name: 'decision_note', type: 'text', nullable: true })
  decisionNote?: string | null;
}
