import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';
import { CharacterEntity } from './character.entity';
import { ChatSystem } from '../features/chat';
import { PlayerSystem } from '../features/player';
import { SceneSystemRendering } from '../features/scene/render';
import SceneSystem from '../features/scene';

@Entity('scenes')
export class SceneEntity {
    @PrimaryGeneratedColumn() id: number;
    @Column({ type: 'varchar', length: 64 }) name: string;
    @Column({ type: 'text' }) description: string;
    @Column({ type: 'float' }) x: number;
    @Column({ type: 'float' }) y: number;
    @Column({ type: 'float' }) z: number;
    @Column({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP' }) created: Date;
    @Column({ type: 'datetime' }) expiration: Date;
    @Column() dimension: number;
    @Column() character_id: number;
    @Column() visible: boolean;

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

    static parameterSettings = {
        name: {
            pattern: "^[A-z0-9 $?!.,']+$",
            maxLength: 32,
        },
        description: {
            pattern: "^[A-z0-9 $?!.,']+$",
            maxLength: 512,
        },
    };

    get remainingTime(): number {
        return Math.max(0, +new Date(this.expiration) - +new Date());
    }

    get emoteColors(): Array4d {
        return [0xc2, 0xa2, 0xda, 0xff];
    }

    get position(): Vector3 {
        return new mp.Vector3(this.x, this.y, this.z);
    }

    notifyCreator(): void {
        const player = PlayerSystem.GetPlayerFromCharacterId(this.character.id);
        if (player) {
            ChatSystem.Notice(player, `Your scene "${this.name} (${this.id})" has expired.`);
        }
    }

    clearFromWorld(): boolean {
        SceneSystemRendering.clear(this.id);
        return true;
    }

    shouldBeExpired(): boolean {
        if (+new Date() > +this.expiration) {
            return true;
        }

        return false;
    }

    render(player?: PlayerMp): boolean {
        if (!this.visible) {
            return false;
        }

        if (player) {
            SceneSystemRendering.push(this, this.emoteColors, player);
        } else {
            SceneSystemRendering.push(this, this.emoteColors);
        }
        return true;
    }
}
