import { Column, Entity, Index, JoinColumn, ManyToOne, OneToMany, OneToOne, PrimaryGeneratedColumn } from 'typeorm';
import { CharacterEntity } from './character.entity';
import { CompanyEntity } from './company.entity';
import { FactionEntity } from './faction.entity';
import { BankAccountEntity } from './bank-account.entity';
import { InvoiceItemEntity } from './invoice-item.entity';
import { VehicleEntity } from './vehicle.entity';
import { MoneyChangeReasons } from '../features/money/money_change_reasons';

@Entity('invoices')
export class InvoiceEntity {
    @PrimaryGeneratedColumn() id: number;
    @Column({ type: 'varchar', length: 128 }) subject: string;
    @Column({ type: 'varchar', length: 128 }) reason: MoneyChangeReasons;
    @Column({ type: 'varchar', length: 64 }) category: string;

    @Column({ type: 'int', nullable: true }) provider_character_id: number | null;
    @Column({ type: 'int', nullable: true }) provider_company_id: number | null;
    @Column({ type: 'int', nullable: true }) provider_faction_id: number | null;
    @Column() provider_bank_account_id: number;
    @Column({ type: 'varchar', length: 512 }) provider_description: string;
    @Column({ type: 'varchar', length: 128, nullable: true }) provider_logo: string | null;

    @Column({ type: 'int', nullable: true }) purchaser_character_id: number | null;
    @Column({ type: 'int', nullable: true }) purchaser_company_id: number | null;
    @Column({ type: 'int', nullable: true }) purchaser_faction_id: number | null;
    @Column({ type: 'varchar', length: 512 }) purchaser_description: string;

    @Column({ type: 'tinyint' }) allow_cash: boolean;
    @Column({ type: 'tinyint' }) allow_card: boolean;

    @Column({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP' }) created: Date;
    @Index()
    @Column()
    created_by_character_id: number;

    @Column({ type: 'datetime' }) due: Date;
    @Column({ type: 'datetime', nullable: true }) invalidated: Date | null;
    @Column({ type: 'datetime', nullable: true }) paid: Date | null;
    @Index()
    @Column()
    paid_by_character_id: number;
    @Column({ type: 'varchar', length: 128 }) paid_description: string;

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

    // Relations

    @ManyToOne(() => CharacterEntity)
    @JoinColumn({ name: 'provider_character_id', referencedColumnName: 'id' })
    providerCharacter: CharacterEntity;

    @ManyToOne(() => CompanyEntity)
    @JoinColumn({ name: 'provider_company_id', referencedColumnName: 'id' })
    providerCompany: CompanyEntity;

    @ManyToOne(() => FactionEntity)
    @JoinColumn({ name: 'provider_faction_id', referencedColumnName: 'id' })
    providerFaction: FactionEntity;

    @ManyToOne(() => CharacterEntity)
    @JoinColumn({ name: 'purchaser_character_id', referencedColumnName: 'id' })
    purchaserCharacter: CharacterEntity;

    @ManyToOne(() => CompanyEntity)
    @JoinColumn({ name: 'purchaser_company_id', referencedColumnName: 'id' })
    purchaserCompany: CompanyEntity;

    @ManyToOne(() => FactionEntity)
    @JoinColumn({ name: 'purchaser_faction_id', referencedColumnName: 'id' })
    purchaserFaction: FactionEntity;

    @OneToOne(() => BankAccountEntity, {
        eager: true,
    })
    @JoinColumn({ name: 'provider_bank_account_id', referencedColumnName: 'id' })
    providerBankAccount: BankAccountEntity;

    @OneToMany(() => InvoiceItemEntity, (iie) => iie.invoice, {
        eager: true,
    })
    items: InvoiceItemEntity[];

    @ManyToOne(() => VehicleEntity, (vehicle) => vehicle.liens)
    @JoinColumn({ name: 'lien_vehicle_id' })
    lienVehicle: VehicleEntity;

    @ManyToOne(() => CharacterEntity)
    @JoinColumn({ name: 'created_by_character_id' })
    createdByCharacter?: CharacterEntity;

    @ManyToOne(() => CharacterEntity)
    @JoinColumn({ name: 'paid_by_character_id' })
    paidByCharacter?: CharacterEntity;

    validate() {
        if (!this.providerCharacter && !this.providerCompany && !this.providerFaction) {
            return false;
        }

        if (!this.providerBankAccount) {
            return false;
        }

        if (!this.purchaserCharacter && !this.purchaserCompany && !this.purchaserFaction) {
            return false;
        }

        if (!this.items.length) {
            return false;
        }

        return true;
    }

    getIdentifier(): string {
        const id = String(this.id).padStart(6, '0');
        if (this.providerCompany) {
            return '1-' + id;
        } else if (this.providerFaction) {
            return '2-' + id;
        } else if (this.providerCharacter) {
            return '3-' + id;
        }

        return '0-' + id;
    }
}
