import { BaseEntity } from "@edr/api-common";
import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
import { Company } from "./company.entity";

export enum ProfileType {
  importer = "importer",
  exporter = "exporter",
  freightForwarder = "freight_forwarder",
  djFreightForwarder = "dj_freight_forwarder",
  transporter = "transporter",
}

export enum ProfileStatus {
  Active = "active",
  Pending = "pending",
  /** Reviewer declined the role; carries a note. Customer can reapply → Pending. */
  Rejected = "rejected",
  Suspended = "suspended",
  Blacklisted = "blacklisted",
}

/**
 * @deprecated Legacy inline shape. Business-license files now live in the
 * FileRecord model (`freight.files`, resource `company_profiles`). Kept only for
 * the by-reference reuse shape consumed by bookings/contracts snapshots.
 */
export interface BusinessLicenseFile {
  name: string;
  url: string;
  size: number;
  mimeType?: string;
}

/**
 * `live` — approved & in effect; `pending_add` — uploaded, awaiting approval;
 * `pending_remove` — live but flagged for deletion on approval.
 */
export type StagedFileStatus = "live" | "pending_add" | "pending_remove";

/**
 * Reviewer verdict on a document, as surfaced to clients. Distinct from
 * {@link StagedFileStatus}: that describes where the file sits in the staged
 * add/remove workflow, this describes whether a reviewer wants it corrected.
 */
export interface FileReviewView {
  /** `change_requested` while the customer still owes a corrected upload. */
  reviewStatus?: "change_requested" | "approved" | null;
  /** The reviewer's reason, shown verbatim to the customer. */
  reviewNote?: string | null;
}

/** A business-license file plus its change-review state, surfaced to clients. */
export interface ProfileLicenseFileView extends FileReviewView {
  id: string;
  name: string;
  size: number;
  mimeType: string;
  status: StagedFileStatus;
}

/** A company-level document (e.g. the PoA letter) with its change-review state. */
export interface CompanyDocumentFileView extends FileReviewView {
  id: string;
  name: string;
  size: number;
  mimeType: string;
  status: StagedFileStatus;
}

@Entity({ schema: "freight", name: "company_profiles" })
@Index(["reference"], { unique: true })
@Index(["type"])
@Index(["companyId"])
export class CompanyProfile extends BaseEntity {
  @Column({ name: "company_id", type: "uuid" })
  companyId!: string;

  @ManyToOne(() => Company, (company) => company.companyProfiles)
  @JoinColumn({ name: "company_id" })
  company!: Company;

  @Column({ name: "type", type: "varchar", length: 32, enum: ProfileType })
  type!: ProfileType;

  /**
   * Official profile reference (e.g. "EX-A00001"). Minted only when the profile
   * is approved (status → Active); pending/unapproved profiles carry NULL.
   * The unique index tolerates this because Postgres treats NULLs as distinct.
   * API responses surface it as "" when absent — see ResponseCompanyProfileDto.
   */
  @Column({
    name: "reference",
    type: "varchar",
    length: 20,
    nullable: true,
  })
  reference!: string | null;

  /**
   * A newly requested operational role is unreviewed, so it defaults to Pending.
   * Only {@link CompaniesService.setCompanyProfileStatus} may promote it to
   * Active — an approved-by-default role would let a customer self-grant a
   * service (e.g. importer) without any documentation review.
   */
  @Column({
    name: "status",
    type: "varchar",
    length: 32,
    default: ProfileStatus.Pending,
  })
  status!: ProfileStatus;

  @Column({
    name: "business_license",
    type: "varchar",
    length: 100,
    nullable: true,
  })
  businessLicense?: string | null;

  /**
   * Business-license documents for this profile, stored directly on the profile
   * (multi-file). The bytes live in object storage; only the metadata/URLs are
   * persisted here — this is intentionally NOT modelled via the FileRecord table.
   */
  @Column({ name: "business_license_files", type: "jsonb", nullable: true })
  businessLicenseFiles?: BusinessLicenseFile[] | null;

  @Column({ name: "attributes", type: "jsonb", nullable: true })
  attributes?: Record<string, any> | null;

  /** Reviewer's note when the role is Rejected (cleared on reapply). */
  @Column({ name: "review_note", type: "text", nullable: true })
  reviewNote?: string | null;

  @Column({ name: "reviewed_by", type: "uuid", nullable: true })
  reviewedBy?: string | null;

  @Column({ name: "reviewed_at", type: "timestamptz", nullable: true })
  reviewedAt?: Date | null;
}
