import * as bootstrap from 'bootstrap';
import LobbyController from '../controllers/lobby-controller.js';
import RankingInput from './ranking-input.js';
import { ReservedBuddyVariables } from 'sfs3-api';

export default class ProfileConfigurator extends HTMLElement
{
    static ONLINE_CHANGE_EVT = 'online-change';
    static BUDDY_SETTING_CHANGE_EVT = 'buddy-setting-change';
    static PLAYER_SETTING_CHANGE_EVT = 'player-setting-change';

    constructor()
    {
        super();

        this._shadowRoot = this.attachShadow({ mode: 'closed' });
    
        this._shadowRoot.innerHTML = `
            <link href="./assets/css/bootstrap.min.css" rel="stylesheet" />
            <link href="./assets/icons/css/fontawesome.min.css" rel="stylesheet" />
            <link href="./assets/icons/css/solid.min.css" rel="stylesheet" />

            <style>
                .state-label {
                    font-variant-caps: all-small-caps;
                }
            </style>

            <button id="profileButton" type="button" class="btn btn-outline-primary btn-sm"><i class="fa-solid fa-user"></i></button>
            <div class="text-secondary">
                <strong class="profileNameLabel"></strong>
                <span id="stateLabel" class="state-label"></span>
            </div>
            <div class="modal" id="profileModal" tabindex="-1" aria-labelledby="profileModalLabel" aria-hidden="true">
                <div class="modal-dialog modal-dialog-centered modal-lg">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h1 class="modal-title fs-5" id="profileModalLabel">User Profile</h1>
                            <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                        </div>
                         <div class="modal-body p-0">
                            <div class="p-3 bg-body-tertiary">
                                <strong>Name:</strong> <span class="profileNameLabel"></span>
                            </div>
                            <div class="p-3 border-top">
                                <div class="row g-5">
                                    <div class="col-lg-6">
                                        <div class="hstack gap-3 justify-content-between">
                                            <h5 class="mb-0">Buddy Profile</h5>
                                            <div class="form-check">
                                                <input class="form-check-input" type="checkbox" id="profileBuddyOnline">
                                                <label class="form-check-label" for="profileBuddyOnline">Online</label>
                                            </div>
                                        </div>
                                        <hr>
                                        <form class="vstack gap-3">
                                            <div class="row">
                                                <label for="profileBuddyNickname" class="col-sm-3 col-form-label">Nickname</label>
                                                <div class="col-sm-9">
                                                    <input type="text" class="form-control" id="profileBuddyNickname">
                                                </div>
                                            </div>
                                            <div class="row">
                                                <label for="profileBuddyYear" class="col-sm-3 col-form-label">Birth year</label>
                                                <div class="col-sm-9">
                                                    <input type="number" class="form-control" id="profileBuddyYear">
                                                </div>
                                            </div>
                                            <div class="row">
                                                <label for="profileBuddyMood" class="col-sm-3 col-form-label">Mood</label>
                                                <div class="col-sm-9">
                                                    <textarea class="form-control" id="profileBuddyMood" rows="2"></textarea>
                                                </div>
                                            </div>
                                            <div class="row">
                                                <label for="profileBuddyState" class="col-sm-3 col-form-label">State</label>
                                                <div class="col-sm-9">
                                                    <select class="form-select" id="profileBuddyState" aria-label="State"></select>
                                                </div>
                                            </div>
                                        </form>
                                    </div>
                                    <div class="col-lg-6">
                                        <h5 class="mb-0">Player Profile</h5>
                                        <hr>
                                        <form class="vstack gap-3">
                                            <div class="row">
                                                <label for="profilePlayerRank" class="col-sm-3 col-form-label">Ranking</label>
                                                <div class="col-sm-9 align-content-center">
                                                    <ranking-input id="profilePlayerRank" value="3"></ranking-input>
                                                </div>
                                            </div>
                                            <div class="row">
                                                <label for="profilePlayerExp" class="col-sm-3 col-form-label">Experience</label>
                                                <div class="col-sm-9">
                                                    <select class="form-select" id="profilePlayerExp" aria-label="Experience">
                                                        <option selected>Novice</option>
                                                        <option>Regular</option>
                                                        <option>Expert</option>
                                                        <option>Master</option>
                                                    </select>
                                                </div>
                                            </div>
                                        </form>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        `;

        this.userNameLabels = this._shadowRoot.querySelectorAll('.profileNameLabel');
        this.profileButton = this._shadowRoot.querySelector('#profileButton');
        this.stateLabel = this._shadowRoot.querySelector('#stateLabel');

        this.onlineCheck = this._shadowRoot.querySelector('#profileBuddyOnline');
        this.nicknameInput = this._shadowRoot.querySelector('#profileBuddyNickname');
        this.stateSelect = this._shadowRoot.querySelector('#profileBuddyState');
        this.yearInput = this._shadowRoot.querySelector('#profileBuddyYear');
        this.moodInput = this._shadowRoot.querySelector('#profileBuddyMood');

        this.rankingInput = this._shadowRoot.querySelector('#profilePlayerRank');
        this.experienceSelect = this._shadowRoot.querySelector('#profilePlayerExp');
        
        // Create profile modal
        this.profileModal = new bootstrap.Modal(this._shadowRoot.querySelector('#profileModal'), {
            backdrop: true,
            focus: true,
            keyboard: true
        });

        // Bind event listeners
        this.boundOnOnlineCheckChange = this.onOnlineCheckChange.bind(this);
        this.boundOnNicknameInputBlur = this.onNicknameInputBlur.bind(this);
        this.boundOnStateSelectChange = this.onStateSelectChange.bind(this);
        this.boundOnYearInputBlur = this.onYearInputBlur.bind(this);
        this.boundOnMoodInputBlur = this.onMoodInputBlur.bind(this);
        this.boundOnRankingInputChange = this.onRankingInputChange.bind(this);
        this.boundOnExperienceSelectChange = this.onExperienceSelectChange.bind(this);
        this.boundOnProfileButtonClick = this.onProfileButtonClick.bind(this);
    }

    connectedCallback()
    {
        // Add listeners to buddy-related controls
        this.onlineCheck.addEventListener('change', this.boundOnOnlineCheckChange);
        this.nicknameInput.addEventListener('blur', this.boundOnNicknameInputBlur);
        this.stateSelect.addEventListener('change', this.boundOnStateSelectChange);
        this.yearInput.addEventListener('blur', this.boundOnYearInputBlur);
        this.moodInput.addEventListener('blur', this.boundOnMoodInputBlur);

        // Add listeners to player-related controls
        this.rankingInput.addEventListener(RankingInput.RANKING_CHANGE_EVT, this.boundOnRankingInputChange);
        this.experienceSelect.addEventListener('change', this.boundOnExperienceSelectChange);

        // Add profile button click listener
        this.profileButton.addEventListener('click', this.boundOnProfileButtonClick);

        // Disable online checkbox and other controls
        // so that interaction is prevented if an error occurs during Buddy list initialization
        this.onlineCheck.disabled = true;
        this.enableBuddyControls(false);
    }

    get playerRanking()
    {
        return Number(this.rankingInput.getAttribute('value'));
    }

    get playerExperience()
    {
        return this.experienceSelect.options[this.experienceSelect.selectedIndex].text;
    }

    displayUserName(name)
    {
        for (let userNameLabel of this.userNameLabels)
            userNameLabel.innerText = name;
    }

    displayUserState(state)
    {
        this.stateLabel.innerText = `[${state}]`;
    }

    /**
     * Show the profile details related to the Buddy List system and add listeners.
     */
    initBuddyProfile(sfsBuddyManager)
    {
        // User online/offline state
        this.onlineCheck.disabled = false;
        this.onlineCheck.checked = sfsBuddyManager.myOnlineState;
        this.enableBuddyControls(sfsBuddyManager.myOnlineState);

        // User nickname
        this.nicknameInput.value = (sfsBuddyManager.myNickname != null ? sfsBuddyManager.myNickname : '');

        // Available states and current user state
        while (this.stateSelect.options.length > 0)
           this.stateSelect.remove(0);

        for (let s of sfsBuddyManager.buddyStates)
        {
            const option = document.createElement('option');
            option.text = s;

            if (s == sfsBuddyManager.myState)
                option.selected = true;

            this.stateSelect.add(option);
        }

        // Buddy variable: user birth year
        const yearVar = sfsBuddyManager.getMyVariable(LobbyController.BUDDYVAR_YEAR);
        this.yearInput.value = ((yearVar != null && !yearVar.isNull) ? yearVar.value : '');

        // Buddy variable: user mood
        const moodVar = sfsBuddyManager.getMyVariable(LobbyController.BUDDYVAR_MOOD);
        this.moodInput.value = ((moodVar != null && !moodVar.isNull) ? moodVar.value : '');
    }

    enableBuddyControls(enable)
    {
        this.nicknameInput.disabled = !enable;
        this.stateSelect.disabled = !enable;
        this.yearInput.disabled = !enable;
        this.moodInput.disabled = !enable;
    }

    // -------------------------------------------------------------------

    onProfileButtonClick(e)
	{
		this.profileModal.show();
	}

    /**
     * Dispatch a custom event to set the user's online/offline state in the Buddy List system.
     */
    onOnlineCheckChange(e)
    {
        const isChecked = e.currentTarget.checked;

        // Dispatch event
        this.dispatchEvent(
            new CustomEvent(ProfileConfigurator.ONLINE_CHANGE_EVT, {
                detail: {
                    goOnline: isChecked
                }
            })
        );

        // Enable/disable controls
        this.enableBuddyControls(isChecked);
    }

    /**
     * Dispatch a custom event to set the user's nickname in the Buddy List system.
     */
    onNicknameInputBlur(e)
    {
        // Dispatch event
        this.dispatchEvent(
            new CustomEvent(ProfileConfigurator.BUDDY_SETTING_CHANGE_EVT, {
                detail: {
                    variable: ReservedBuddyVariables.BV_NICKNAME,
                    value: e.currentTarget.value,
                }
            })
        );
    }

    /**
     * Dispatch a custom event to set the user's state in the Buddy List system.
     */
    onStateSelectChange(e)
    {
        // Dispatch event
        this.dispatchEvent(
            new CustomEvent(ProfileConfigurator.BUDDY_SETTING_CHANGE_EVT, {
                detail: {
                    variable: ReservedBuddyVariables.BV_STATE,
                    value: e.currentTarget.value,
                }
            })
        );
    }

    /**
     * Dispatch a custom event to set the user's birth year in the Buddy List system.
     */
    onYearInputBlur(e)
    {
        // Dispatch event
        this.dispatchEvent(
            new CustomEvent(ProfileConfigurator.BUDDY_SETTING_CHANGE_EVT, {
                detail: {
                    variable: LobbyController.BUDDYVAR_YEAR,
                    value: (e.currentTarget.value != '' ?  Number(e.currentTarget.value) : null),
                }
            })
        );
    }

    /**
     * Dispatch a custom event to set the user's mood in the Buddy List system.
     */
    onMoodInputBlur(e)
    {
        // Dispatch event
        this.dispatchEvent(
            new CustomEvent(ProfileConfigurator.BUDDY_SETTING_CHANGE_EVT, {
                detail: {
                    variable: LobbyController.BUDDYVAR_MOOD,
                    value: e.currentTarget.value,
                }
            })
        );
    }

    /**
     * Dispatch a custom event to set the related user variable.
     */
    onRankingInputChange(e)
    {
        // Dispatch event
        this.dispatchEvent(
            new CustomEvent(ProfileConfigurator.PLAYER_SETTING_CHANGE_EVT, {
                detail: {
                    variable: LobbyController.USERVAR_RANKING,
                    value: e.detail.ranking,
                }
            })
        );
    }

    /**
     * Dispatch a custom event to set the related user variable.
     */
    onExperienceSelectChange(e)
    {
        // Dispatch event
        this.dispatchEvent(
            new CustomEvent(ProfileConfigurator.PLAYER_SETTING_CHANGE_EVT, {
                detail: {
                    variable: LobbyController.USERVAR_EXPERIENCE,
                    value: e.currentTarget.value,
                }
            })
        );
    }
}

customElements.define('profile-configurator', ProfileConfigurator);