
interface IBaseEntityProperties {
    tableName: string;
    fa: string;
    en: string | null;
    ar: string | null;
    sp: string | null;
    fr: string | null;
    properties: IBasePropertyJson[];
}

interface IBasePropertyJson {
    dataType: IBasePropertyDataType;
    fieldName: string;
    fa: string;
    en: string | null;
    ar: string | null;
    sp: string | null;
    fr: string | null;
}

export class BaseEntityProperties {
    public properties: BaseProperty[];

    constructor(
        public tableName: string,
        public FA: string,
        public EN?: string,
        public AR?: string,
        public SP?: string,
        public FR?: string,
    ) {
        this.properties = [];
    }

    private Add = (property: BaseProperty) => {
        this.properties.push(property);
    }

    static buildNew(jsons: IBaseEntityProperties[]): BaseEntityProperties[] {
        let finalJsons: IBaseEntityProperties[];
        if (Array.isArray(jsons)) {
            finalJsons = jsons;
        } else {
            finalJsons = [jsons];
        }

        const results = finalJsons.map(json => {
            const result = new BaseEntityProperties(json.tableName, json.fa, json.en || undefined, json.ar || undefined, json.sp || undefined, json.fr || undefined);
            json.properties.forEach(prop => {
                result.Add(BaseProperty.buildNew(prop))
            });
            return result;
        });
        return results;
    }
}


type IBasePropertyDataType = 'int' | 'string' | 'dateTime' | 'dateShamsi' | 'float';

export class BaseProperty {
    constructor(
        public dataType: IBasePropertyDataType,
        public fieldName: string,
        public FA: string,
        public EN: string | null,
        public AR: string | null,
        public SP: string | null,
        public FR: string | null
    ) {

    }

    static buildNew(entityJson: IBasePropertyJson): BaseProperty {
        return new BaseProperty(entityJson.dataType, entityJson.fieldName, entityJson.fa, entityJson.en, entityJson.ar, entityJson.sp, entityJson.fr);
    }
}

export class BasePropertyFactory {
    getCurrentProperty(entity: BaseEntityProperties | undefined, fieldName: string): BaseProperty | undefined {
        if (fieldName === '') {
            return undefined;
        }
        if (!entity) {
            return undefined
        }
        if (!entity.properties) {
            return undefined
        }
        if (entity.properties.length === 0) {
            return undefined
        }
        return entity.properties.find(i => i.fieldName === fieldName);
    }

    getCurrentEntity(tableName: string): BaseEntityProperties | undefined {
        if (tableName === '') {
            return undefined;
        }
        return this.entities?.find(i => i.tableName === tableName);
    }

    public entities?: BaseEntityProperties[];

    setEntities = (entities: IBaseEntityProperties[]) => {
        this.entities = BaseEntityProperties.buildNew(entities);
    }

    static buildNew() {
        return new BasePropertyFactory();
    }
}