import { Column, CreateDateColumn, Entity, Index, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';
import { PropertyEntity } from './property.entity';
import { ItemTypeEntity } from './item-type.entity';
import { TruckingLocationEntity } from './trucking-location.entity';
import { TruckingContractEntity } from './trucking-contract.entity';

export type TruckingDeliveryRequestStatus = 'open' | 'claimed' | 'delivered' | 'cancelled';
export type TruckingDeliveryPaySource = 'npc' | 'business';

@Entity('trucking_delivery_requests')
export class TruckingDeliveryRequestEntity {
    @PrimaryGeneratedColumn()
    id: number;

    /** Null for NPC-sourced requests — use requester_name instead */
    @Column({ type: 'int', nullable: true })
    property_id: number | null;

    /** Display name for NPC requests (never shown to players as "NPC") */
    @Column({ type: 'varchar', length: 256, nullable: true })
    requester_name: string | null;

    @Column()
    item_type_id: number;

    @Column()
    quantity: number;

    @Column()
    pickup_location_id: number;

    @Index()
    @Column({ type: 'enum', enum: ['open', 'claimed', 'delivered', 'cancelled'], default: 'open' })
    status: TruckingDeliveryRequestStatus;

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

    @Column({ type: 'timestamp', nullable: true })
    claimed_at: Date | null;

    @Column({ type: 'int', default: 0 })
    reward: number;

    @Column({ type: 'enum', enum: ['npc', 'business'], default: 'npc' })
    pay_source: TruckingDeliveryPaySource;

    @Column({ type: 'int', default: 0 })
    min_cdl_level: number;

    @CreateDateColumn()
    created_at: Date;

    @ManyToOne(() => PropertyEntity, { nullable: true, onDelete: 'CASCADE' })
    @JoinColumn({ name: 'property_id' })
    property: PropertyEntity | null;

    @ManyToOne(() => ItemTypeEntity)
    @JoinColumn({ name: 'item_type_id' })
    itemType: ItemTypeEntity;

    @ManyToOne(() => TruckingLocationEntity)
    @JoinColumn({ name: 'pickup_location_id' })
    pickupLocation: TruckingLocationEntity;

    /** Delivery trucking location — set on NPC requests (property_id is null) */
    @Column({ type: 'int', nullable: true })
    delivery_location_id: number | null;

    @ManyToOne(() => TruckingLocationEntity, { nullable: true })
    @JoinColumn({ name: 'delivery_location_id' })
    deliveryLocation: TruckingLocationEntity | null;

    /** Set when this request was generated from a company contract */
    @Column({ type: 'int', nullable: true })
    contract_id: number | null;

    /** Whether this delivery requires a tractor-trailer (true) or a straight truck (false) */
    @Column({ type: 'boolean', default: false })
    requires_trailer: boolean;

    @ManyToOne(() => TruckingContractEntity, { nullable: true, onDelete: 'SET NULL' })
    @JoinColumn({ name: 'contract_id' })
    contract: TruckingContractEntity | null;

    /** Resolved display name — never exposes NPC source */
    getRequesterName(): string {
        return this.requester_name ?? this.property?.name ?? this.property?.company?.name ?? 'Business';
    }

    /** Delivery coordinates — property for business requests, trucking location for NPC */
    getDeliveryCoords(): { x: number; y: number; z: number } {
        if (this.property) {
            return { x: this.property.enter_x, y: this.property.enter_y, z: this.property.enter_z ?? 0 };
        }
        if (this.deliveryLocation) {
            return { x: this.deliveryLocation.x, y: this.deliveryLocation.y, z: this.deliveryLocation.z };
        }
        return { x: 0, y: 0, z: 0 };
    }

    /** Display name for delivery destination */
    getDeliveryName(): string {
        return this.property?.name ?? this.property?.company?.name ?? this.deliveryLocation?.name ?? this.requester_name ?? 'Destination';
    }
}
