/**
 * The list of all clients that have registered with the logger, in addition to their current capture state.
 */
import React from "react";
import LoggerClientControl from "./LoggerClientControl";
import LoggerButton from "../../../../LoggerButton";
import LoggerStore from "../../../../../stores/LoggerStore";

interface IProps {
	fileMode?: boolean;
	height?: number;
}
interface IState {
	clientNames: any[];
	registeredClients: any;
	hideInactive: boolean;
	fileMode: boolean | undefined;
	clientMode: string;
	initialClientStateDefault: any;
	clientListFilter: string;
	showFullClientNames: boolean;
}

export default class LoggerClientControlList extends React.Component<IProps, IState> {
	constructor(props: IProps) {
		super(props);

		this.state = {
			clientNames: LoggerStore.getRegisteredClientNames(),
			registeredClients: LoggerStore.getRegisteredClients(),
			hideInactive: LoggerStore.getHideInactiveState(),
			fileMode: this.props.fileMode,
			clientMode: LoggerStore.getClientMode(),
			initialClientStateDefault: LoggerStore.getInitialClientStateDefault(),
			clientListFilter: "",
			showFullClientNames: false,
		};

		this.loggerRegister = this.loggerRegister.bind(this);
		this.loggerUnregister = this.loggerUnregister.bind(this);
		this.getHideInactiveState = this.getHideInactiveState.bind(this);
		this.fileMode = this.fileMode.bind(this);
		this.getNewRegisteredClients = this.getNewRegisteredClients.bind(this);
		this.changeClientMode = this.changeClientMode.bind(this);
		this.clientModeButtonStyle = this.clientModeButtonStyle.bind(this);
		this.toggleClientNameLimit = this.toggleClientNameLimit.bind(this);
		this.getNewInitialClientStateDefault = this.getNewInitialClientStateDefault.bind(this);
		this.handleClientListFilterChange = this.handleClientListFilterChange.bind(this);
	}

	componentDidMount() {
		LoggerStore.addListener("LoggerRegister", this.loggerRegister);
		LoggerStore.addListener("LoggerUnregister", this.loggerUnregister);
		LoggerStore.addListener("newHideInactiveState", this.getHideInactiveState);
		LoggerStore.addListener("FileMode", this.fileMode);
		LoggerStore.addListener("ChangeClientMode", this.changeClientMode);
		LoggerStore.addListener("newInitialClientStateDefault", this.getNewInitialClientStateDefault);
		LoggerStore.addListener("newShowClientState", this.getNewRegisteredClients);
	}

	componentWillUnmount() {
		LoggerStore.removeListener("LoggerRegister", this.loggerRegister);
		LoggerStore.removeListener("LoggerUnregister", this.loggerUnregister);
		LoggerStore.removeListener("newHideInactiveState", this.getHideInactiveState);
		LoggerStore.removeListener("FileMode", this.fileMode);
		LoggerStore.removeListener("ChangeClientMode", this.changeClientMode);
		LoggerStore.removeListener("newInitialClientStateDefault", this.getNewInitialClientStateDefault);
		LoggerStore.removeListener("newShowClientState", this.getNewRegisteredClients);
	}

	loggerRegister() {
		const clientNames = LoggerStore.getRegisteredClientNames();
		this.setState({ clientNames });
	}

	loggerUnregister() {
		const clientNames = LoggerStore.getRegisteredClientNames();
		this.setState({ clientNames });
	}

	fileMode() {
		const fileModeState = LoggerStore.getFileMode();
		this.setState({ fileMode: fileModeState });
	}

	allToggle() {
		LoggerStore.toggleShowAllClients();
	}

	toggleHideInactive() {
		LoggerStore.toggleHideInactive();
	}

	getHideInactiveState() {
		const newState = LoggerStore.getHideInactiveState();
		this.setState({ hideInactive: newState });
	}

	default() {
		LoggerStore.defaultShowClientAll();
	}

	devMode() {
		LoggerStore.devMode();
	}

	systemMode() {
		LoggerStore.systemMode();
	}

	perfMode() {
		LoggerStore.perfMode();
	}

	getNewRegisteredClients() {
		this.setState({
			registeredClients: LoggerStore.getRegisteredClients(),
		});
	}

	changeClientMode() {
		const newMode = LoggerStore.getClientMode();
		this.setState({ clientMode: newMode });
	}

	clientModeButtonStyle(mode) {
		if (mode === this.state.clientMode) {
			return "active";
		}
		return "inactive";
	}

	errorsToggleInitialDefault() {
		LoggerStore.toggleInitialClientErrorsDefault();
	}

	warningsToggleInitialDefault() {
		LoggerStore.toggleInitialClientWarningsDefault();
	}

	infoToggleInitialDefault() {
		LoggerStore.toggleInitialClientInfoDefault();
	}

	logsToggleInitialDefault() {
		LoggerStore.toggleInitialClientLogsDefault();
	}

	debugToggleInitialDefault() {
		LoggerStore.toggleInitialClientDebugDefault();
	}

	verboseToggleInitialDefault() {
		LoggerStore.toggleInitialClientVerboseDefault();
	}

	localOnlyToggleInitialDefault() {
		LoggerStore.toggleInitialClientLocalOnlyDefault();
	}

	getNewInitialClientStateDefault() {
		const newInitialClientStateDefault = LoggerStore.getInitialClientStateDefault();
		this.setState({ initialClientStateDefault: newInitialClientStateDefault });
	}

	handleClientListFilterChange(e) {
		this.setState({
			clientListFilter: e.target.value,
		});
	}

	toggleClientNameLimit() {
		const currentState = this.state.showFullClientNames;

		this.setState({
			showFullClientNames: !currentState,
		});
	}

	render() {
		const { registeredClients } = this.state;

		const loggerClientSorter = (clientNameLHS: string, clientNameRHS: string) => {
			const lhs = registeredClients[clientNameLHS]?.displayName ?? "";
			const rhs = registeredClients[clientNameRHS]?.displayName ?? "";
			return lhs.toLowerCase().localeCompare(rhs.toLowerCase());
		};

		const LoggerList = this.state.clientNames
			.sort(loggerClientSorter)
			.filter((name) => {
				if (this.state.clientListFilter !== "") {
					return name && name.toLowerCase().includes(this.state.clientListFilter.toLowerCase());
				}
				return true;
			})
			.map((name, index) => {
				const client = registeredClients[name];
				const viewId = client?.viewId;
				const windowName = client?.name;
				const displayName = client?.displayName ?? client?.name ?? "Unnamed Window";
				const centralLoggerNamePrefix = client?.centralLoggerNamePrefix;
				return (
					<LoggerClientControl
						key={index}
						clientName={name}
						fileMode={this.state.fileMode}
						viewId={viewId}
						windowName={windowName}
						displayName={displayName}
						centralLoggerNamePrefix={centralLoggerNamePrefix}
					/>
				);
			});
		return (
			<div className="logger-clients-section topDiv">
				{!this.state.fileMode && LoggerList.length === 0 ? null : (
					<div className="fsbl-logger-client-row">
						<div className="fsbl-logger-button-group fsbl-logger-client-list-actions">
							<LoggerButton onClick={this.allToggle}>Toggle All</LoggerButton>
							<LoggerButton
								className="fsbl-logger-toggle"
								active={this.state.hideInactive}
								onClick={this.toggleHideInactive}
							>
								Hide Uncaptured
							</LoggerButton>
							<LoggerButton active={this.state.showFullClientNames} onClick={this.toggleClientNameLimit}>
								{this.state.showFullClientNames ? "Short Client Names" : "Full Client Names"}
							</LoggerButton>
						</div>
						<div>
							<div className="fsbl-logger-buttons">
								<div className="fsbl-logger-button-group-label">Select All</div>
								<div className="fsbl-logger-button-group">
									<LoggerButton
										className="fsbl-logger-toggle"
										active={this.state.initialClientStateDefault.Error}
										onClick={this.errorsToggleInitialDefault}
									>
										Errors
									</LoggerButton>
									<LoggerButton
										className="fsbl-logger-toggle"
										active={this.state.initialClientStateDefault.Warn}
										onClick={this.warningsToggleInitialDefault}
									>
										Warning
									</LoggerButton>
									<LoggerButton
										className="fsbl-logger-toggle"
										active={this.state.initialClientStateDefault.Log}
										onClick={this.logsToggleInitialDefault}
									>
										Log
									</LoggerButton>
									<LoggerButton
										className="fsbl-logger-toggle"
										active={this.state.initialClientStateDefault.Info}
										onClick={this.infoToggleInitialDefault}
									>
										Info
									</LoggerButton>
									<LoggerButton
										className="fsbl-logger-toggle"
										active={this.state.initialClientStateDefault.Debug}
										onClick={this.debugToggleInitialDefault}
									>
										Debug
									</LoggerButton>
									<LoggerButton
										className="fsbl-logger-toggle"
										active={this.state.initialClientStateDefault.Verbose}
										onClick={this.verboseToggleInitialDefault}
									>
										Verbose
									</LoggerButton>
									{/* <LoggerButton
									className="fsbl-logger-toggle"
									active={this.state.initialClientStateDefault.LocalOnly}
									onClick={this.localOnlyToggleInitialDefault}>Local Console Only</LoggerButton> */}
								</div>
							</div>
						</div>
					</div>
				)}
				{this.state.fileMode ? (
					<div className="logger-row">
						<div className="fsbl-logger-button-group">
							<div className="fsbl-logger-buttons">
								{/* turn off certain buttons when in fileMode */}
								<span className="fileStyle">File Mode</span>
							</div>
						</div>
					</div>
				) : null}

				<div className="fsbl-logger-buttons">
					<input
						placeholder="Filter List"
						value={this.state.clientListFilter}
						onChange={this.handleClientListFilterChange}
					/>
					{this.state.clientListFilter !== "" && (
						<div>Filter hiding {this.state.clientNames.length - LoggerList.length} clients.</div>
					)}
				</div>

				<div
					style={{ height: this.props.height }}
					className={
						this.state.showFullClientNames ? "logger-client-list logger-client-list--full-names" : "logger-client-list"
					}
				>
					{LoggerList}
				</div>
			</div>
		);
	}
}
