import { Column, Entity, getRepository, JoinColumn, ManyToOne, OneToMany, PrimaryGeneratedColumn } from 'typeorm';
import { FactionRankEntity } from './factionrank.entity';
import { BankAccountEntity } from './bank-account.entity';
import { CharacterEntity } from './character.entity';
import { MDCNoticeEntity } from './mdc-notice.entity';
import { PropertyEntity } from './property.entity';
import { VehicleOrderEntity } from './vehicle-order.entity';
import { PetEntity } from './pet.entity';
import { VehicleEntity } from './vehicle.entity';

@Entity('factions')
export class FactionEntity {
    @PrimaryGeneratedColumn() id: number;
    @Column({ type: 'varchar', length: 64, unique: true }) name: string;
    @Column({ type: 'varchar', length: 8, unique: true }) abbreviation: string;
    @Column({ type: 'varchar', length: 16 }) type: string;
    @Column({ type: 'varchar', length: 10 }) chat_color: string;
    @Column() number_plate_type: number;
    @Column({ type: 'varchar', length: 255 }) logo: string;
    @Column({ type: 'int', default: null, nullable: true }) owner: number | null;
    @Column() join_rank: number;
    @Column({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP' }) created: string;
    @Column({ type: 'varchar', length: 64, nullable: true }) stamp: string | null;
    @Column() beta_coins: number;

    @ManyToOne(() => CharacterEntity, (character) => character.faction)
    @JoinColumn({ name: 'owner' })
    character?: CharacterEntity;

    @OneToMany(() => BankAccountEntity, (bankAccount) => bankAccount.faction)
    bankAccounts: BankAccountEntity[];

    @OneToMany(() => FactionRankEntity, (rank) => rank.faction)
    ranks: FactionRankEntity[];

    @OneToMany(() => CharacterEntity, (character) => character.faction)
    members: CharacterEntity[];

    @OneToMany(() => PropertyEntity, (property) => property.faction)
    properties: PropertyEntity[];

    @OneToMany(() => MDCNoticeEntity, (mdcNotice) => mdcNotice.faction)
    mdcNotices: MDCNoticeEntity[];

    @OneToMany(() => PetEntity, (pet) => pet.character_id)
    pets: PetEntity[];

    @OneToMany(() => VehicleEntity, (vehicle) => vehicle.faction)
    vehicles: VehicleEntity[];

    @OneToMany(() => VehicleOrderEntity, (voe) => voe.character)
    vehicleOrders: VehicleOrderEntity[];

    factionRankPermissionAccess: {
        id: number;
        name: string;
        description: string;
    }[] = [];

    chatDisabled: boolean;

    async save(): Promise<FactionEntity> {
        return await getRepository(FactionEntity).save(this);
    }

    getRankName(rankId: number): string | undefined {
        return this.ranks.find((r) => r.sort_id === rankId)?.name;
    }

    getAgencyNo() {
        return String(this.id).padStart(4, '0');
    }

    getName(): string {
        return this.name || `Faction #${this.id}`;
    }

    getEntityType(): 'faction' {
        return 'faction';
    }
}

export const FactionTypes = ['law', 'medic', 'gov', 'gang', 'ocg'];
