// Copyright 2015-2025, University of Colorado Boulder
/**
 * UI parts for update-related dialogs
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */
import { string_joist_updates_checking_StringProperty } from './strings/updates/checking.js';
import { string_joist_updates_upToDate_StringProperty } from './strings/updates/upToDate.js';
import { string_joist_updates_outOfDate_StringProperty } from './strings/updates/outOfDate.js';
import { string_joist_updates_newVersionAvailable_StringProperty } from './strings/updates/newVersionAvailable.js';
import { string_joist_updates_yourCurrentVersion_StringProperty } from './strings/updates/yourCurrentVersion.js';
import { string_joist_updates_getUpdate_StringProperty } from './strings/updates/getUpdate.js';
import { string_joist_updates_noThanks_StringProperty } from './strings/updates/noThanks.js';
import { string_joist_updates_offline_StringProperty } from './strings/updates/offline.js';
import '../../globals.js';
import DerivedProperty from '../../axon/js/DerivedProperty.js';
import merge from '../../phet-core/js/merge.js';
import StringUtils from '../../phetcommon/js/util/StringUtils.js';
import PhetFont from '../../scenery-phet/js/PhetFont.js';
import SpinningIndicatorNode from '../../scenery-phet/js/SpinningIndicatorNode.js';
import VoicingText from '../../scenery/js/accessibility/voicing/nodes/VoicingText.js';
import HBox from '../../scenery/js/layout/nodes/HBox.js';
import VBox from '../../scenery/js/layout/nodes/VBox.js';
import Path from '../../scenery/js/nodes/Path.js';
import Rectangle from '../../scenery/js/nodes/Rectangle.js';
import RichText from '../../scenery/js/nodes/RichText.js';
import VStrut from '../../scenery/js/nodes/VStrut.js';
import allowLinksProperty from '../../scenery/js/util/allowLinksProperty.js';
import openPopup from '../../scenery/js/util/openPopup.js';
import TextPushButton from '../../sun/js/buttons/TextPushButton.js';
import checkSolidShape from '../../sun/js/shapes/checkSolidShape.js';
import exclamationSolidShape from '../../sun/js/shapes/exclamationSolidShape.js';
import joist from './joist.js';
import updateCheck from './updateCheck.js';
import UpdateState from './UpdateState.js';
// constants
const UPDATE_TEXT_FONT = new PhetFont(14);
const MAX_WIDTH = 550; // Maximum width of the resulting update items
const UpdateNodes = {
    /**
     * "Checking" state node. With two size options (if options.big == true, it will be bigger)
     *
     * [options] - passed to the Node
     * returns step( dt ) and stepListener (bound to the node itself)
     * (joist-internal)
     */
    createCheckingNode: function (options) {
        const spinningIndicatorNode = new SpinningIndicatorNode({ diameter: options.big ? 24 : 18 });
        const checkingNode = new HBox(merge({
            spacing: options.big ? 10 : 8,
            maxWidth: MAX_WIDTH,
            children: [
                spinningIndicatorNode,
                new VoicingText(string_joist_updates_checking_StringProperty, {
                    font: new PhetFont(options.big ? 16 : 14),
                    fontWeight: options.big ? 'bold' : 'normal'
                })
            ]
        }, options));
        checkingNode.step = function (dt) {
            if (updateCheck.stateProperty.value === UpdateState.CHECKING) {
                spinningIndicatorNode.step(dt);
            }
        };
        checkingNode.stepListener = checkingNode.step.bind(checkingNode);
        return checkingNode;
    },
    /**
     * "Up-to-date" state node
     * [options] - passed to the Node
     * (joist-internal)
     */
    createUpToDateNode: function (options) {
        return new HBox(merge({
            spacing: 8,
            maxWidth: MAX_WIDTH,
            children: [
                new Rectangle(0, 0, 20, 20, 5, 5, {
                    fill: '#5c3',
                    scale: options.big ? 1.2 : 1,
                    children: [
                        new Path(checkSolidShape, {
                            fill: '#fff',
                            scale: 0.48,
                            centerX: 10,
                            centerY: 10
                        })
                    ]
                }),
                new VoicingText(string_joist_updates_upToDate_StringProperty, {
                    font: new PhetFont(options.big ? 16 : 14),
                    fontWeight: options.big ? 'bold' : 'normal'
                })
            ]
        }, options));
    },
    /**
     * "Out-of-date" state node for the "About" dialog.
     * [options] - passed to the Node
     * (joist-internal)
     */
    createOutOfDateAboutNode: function (options) {
        const stringProperty = new DerivedProperty([string_joist_updates_outOfDate_StringProperty, allowLinksProperty], (outOfDateString, allowLinks) => {
            return allowLinks ? `<a href="{{url}}">${outOfDateString}</a>` : outOfDateString;
        });
        const links = { url: updateCheck.updateURL };
        const linkNode = new RichText(stringProperty, {
            links: links,
            font: UPDATE_TEXT_FONT
        });
        return new HBox(merge({
            spacing: 8,
            maxWidth: MAX_WIDTH,
            children: [
                new Path(exclamationSolidShape, {
                    fill: '#E87600', // "safety orange", according to Wikipedia
                    scale: 0.381
                }),
                linkNode
            ],
            // pdom
            tagName: 'div'
        }, options));
    },
    /**
     * "Out-of-date" state node for the "Check for update" dialog.
     * dialog - the dialog, so that it can be closed with the "No thanks..." button
     * [options] - passed to the Node
     * (joist-internal)
     */
    createOutOfDateDialogNode: function (dialog, ourVersionString, latestVersionString, options) {
        const latestVersionStringProperty = new DerivedProperty([string_joist_updates_newVersionAvailable_StringProperty], string => {
            return StringUtils.format(string, latestVersionString);
        });
        const ourVersionStringProperty = new DerivedProperty([string_joist_updates_yourCurrentVersion_StringProperty], string => {
            return StringUtils.format(string, ourVersionString);
        });
        return new VBox(merge({
            spacing: 15,
            maxWidth: MAX_WIDTH,
            children: [
                new VBox({
                    spacing: 5, align: 'left', children: [
                        new VoicingText(latestVersionStringProperty, {
                            font: new PhetFont(16), fontWeight: 'bold'
                        }),
                        new VoicingText(ourVersionStringProperty, {
                            font: UPDATE_TEXT_FONT
                        })
                    ]
                }),
                new HBox({
                    spacing: 25, children: [
                        new TextPushButton(string_joist_updates_getUpdate_StringProperty, {
                            visibleProperty: allowLinksProperty,
                            baseColor: '#6f6', font: UPDATE_TEXT_FONT, listener: function () {
                                openPopup(updateCheck.updateURL); // open in a new window/tab
                            }
                        }),
                        new TextPushButton(string_joist_updates_noThanks_StringProperty, {
                            baseColor: '#ddd', font: UPDATE_TEXT_FONT, listener: function () {
                                dialog.hide();
                                // Closing the dialog is handled by the Dialog listener itself, no need to add code to close it here.
                            }
                        })
                    ]
                })
            ]
        }, options));
    },
    /**
     * "Offline" state node
     * [options] - passed to the Node
     * (joist-internal)
     */
    createOfflineNode: function (options) {
        return new HBox(merge({
            spacing: 0,
            maxWidth: MAX_WIDTH,
            children: [
                new VStrut(20), // spacer to match layout of other nodes
                new VoicingText(string_joist_updates_offline_StringProperty, {
                    font: new PhetFont(options.big ? 16 : 14),
                    fontWeight: options.big ? 'bold' : 'normal'
                })
            ]
        }, options));
    }
};
joist.register('UpdateNodes', UpdateNodes);
export default UpdateNodes;
