import {UIElement} from "./UIElement";
import {Tag, TagUtils} from "../Logic/Tags";
import {FilteredLayer} from "../Logic/FilteredLayer";
import Translations from "./i18n/Translations";
import Combine from "./Base/Combine";
import {SubtleButton} from "./Base/SubtleButton";
import Locale from "./i18n/Locale";
import State from "../State";
import {UIEventSource} from "../Logic/UIEventSource";
import {Img} from "./Img";
import Svg from "../Svg";
/**
 * Asks to add a feature at the last clicked location, at least if zoom is sufficient
 */
export class SimpleAddUI extends UIElement {
    private readonly _addButtons: UIElement[];
    
    private _loginButton : UIElement;
    
    private _confirmPreset: UIEventSource<{
        description: string | UIElement,
        name: string | UIElement,
        icon: string,
        tags: Tag[],
        layerToAddTo: FilteredLayer
    }>
        = new UIEventSource(undefined);
    private confirmButton: UIElement = undefined;
    private openLayerControl: UIElement;
    private cancelButton: UIElement;
    private goToInboxButton: UIElement = new SubtleButton(Svg.envelope_ui(), 
        Translations.t.general.goToInbox, {url:"https://www.openstreetmap.org/messages/inbox", newTab: false});
    constructor() {
        super(State.state.locationControl);
        this.ListenTo(Locale.language);
        this.ListenTo(State.state.osmConnection.userDetails);
        this.ListenTo(State.state.layerUpdater.runningQuery);
        this.ListenTo(this._confirmPreset);
        this.ListenTo(State.state.locationControl);
        
        this._loginButton = Translations.t.general.add.pleaseLogin.Clone().onClick(() => State.state.osmConnection.AttemptLogin());
        
        this._addButtons = [];
        this.SetStyle("font-size:large");
        
        const self = this;
        for (const layer of State.state.filteredLayers.data) {
            this.ListenTo(layer.isDisplayed);
            const presets = layer.layerDef.presets;
            for (const preset of presets) {
                let icon: string = layer.layerDef.icon.GetRenderValue(
                    TagUtils.KVtoProperties(preset.tags ?? [])).txt
                const csCount = State.state.osmConnection.userDetails.data.csCount;
                let tagInfo = "";
                if (csCount > State.userJourney.tagsVisibleAt) {
                    tagInfo = preset.tags.map(t => t.asHumanString(false, true)).join("&");
                    tagInfo = `
${tagInfo}`
                }
                const button: UIElement =
                    new SubtleButton(
                        icon,
                        new Combine([
                            "",
                            preset.title,
                            "",
                            preset.description !== undefined ? new Combine(["
", preset.description]) : "",
                            tagInfo
                        ])
                    ).onClick(
                        () => {
                            self.confirmButton = new SubtleButton(icon,
                                new Combine([
                                    "",
                                    Translations.t.general.add.confirmButton.Subs({category: preset.title}),
                                    "
",
                                    preset.description !== undefined ? preset.description : ""]));
                            self.confirmButton.onClick(self.CreatePoint(preset.tags, layer));
                            self._confirmPreset.setData({
                                tags: preset.tags,
                                layerToAddTo: layer,
                                name: preset.title,
                                description: preset.description,
                                icon: icon
                            });
                            self.Update();
                        }
                    )
                this._addButtons.push(button);
            }
        }
        this.cancelButton = new SubtleButton(Svg.close_ui(),
            Translations.t.general.cancel
        ).onClick(() => {
            self._confirmPreset.setData(undefined);
        })
        this.openLayerControl = new SubtleButton(Svg.layers_ui(),
            Translations.t.general.add.openLayerControl
        ).onClick(() => {
            State.state.layerControlIsOpened.setData(true);
        })
    }
    private CreatePoint(tags: Tag[], layerToAddTo: FilteredLayer) {
        return () => {
            const loc = State.state.bm.LastClickLocation.data;
            let feature = State.state.changes.createElement(tags, loc.lat, loc.lon);
            layerToAddTo.AddNewElement(feature);
            State.state.selectedElement.setData({feature: feature});
        }
    }
    InnerRender(): string {
        const userDetails = State.state.osmConnection.userDetails;
        if (this._confirmPreset.data !== undefined) {
            
            if(!this._confirmPreset.data.layerToAddTo.isDisplayed.data){
                return new Combine([
                    Translations.t.general.add.layerNotEnabled.Subs({layer: this._confirmPreset.data.layerToAddTo.layerDef.name})
                        .SetClass("alert"),
                    this.openLayerControl,
                    
                    this.cancelButton
                ]).Render();
            }
            let tagInfo = "";
            const csCount = State.state.osmConnection.userDetails.data.csCount;
            if (csCount > State.userJourney.tagsVisibleAt) {
                tagInfo = this._confirmPreset.data .tags.map(t => t.asHumanString(csCount > State.userJourney.tagsVisibleAndWikiLinked, true)).join("&");
                tagInfo = `
More information about the preset: ${tagInfo}`
            }
            return new Combine([
                Translations.t.general.add.confirmIntro.Subs({title: this._confirmPreset.data.name}),
                userDetails.data.dryRun ? "TESTING - changes won't be saved" : "",
                this.confirmButton,
                this.cancelButton,
                tagInfo
            ]).Render();
        }
        let header: UIElement = Translations.t.general.add.header;
        if (userDetails === undefined) {
            return header.Render();
        }
        if (!userDetails.data.loggedIn) {
            return new Combine([header, this._loginButton]).Render()
        }
        if (userDetails.data.unreadMessages > 0 && userDetails.data.csCount < State.userJourney.addNewPointWithUnreadMessagesUnlock) {
            return new Combine([header,
                Translations.t.general.readYourMessages.Clone().SetClass("alert"),
                this.goToInboxButton
            ]).Render();
        }
        if (userDetails.data.dryRun) {
            header = new Combine([header,
                "",
                "Test mode - changes won't be saved",
                ""
            ]);
        }
        if (userDetails.data.csCount < State.userJourney.addNewPointsUnlock) {
            return new Combine([header, "",
                Translations.t.general.fewChangesBefore,
                ""]).Render();
        }
        if (State.state.locationControl.data.zoom < State.userJourney.minZoomLevelToAddNewPoints) {
            return new Combine([header, Translations.t.general.add.zoomInFurther]).Render()
        }
        if (State.state.layerUpdater.runningQuery.data) {
            return new Combine([header, Translations.t.general.add.stillLoading]).Render()
        }
        return header.Render() + new Combine(this._addButtons).SetClass("add-popup-all-buttons").Render();
    }
}