import { css, html, LitElement, nothing } from 'lit';
import { customElement, property, query } from 'lit/decorators.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
import { until } from 'lit/directives/until.js';
import type { GlExtensionCommands } from '../../../../constants.commands.js';
import type { Source } from '../../../../constants.telemetry.js';
import type { Promo } from '../../../../plus/gk/models/promo.js';
import { createCommandLink } from '../../../../system/commands.js';
import { focusOutline } from './styles/lit/a11y.css.js';

@customElement('gl-promo')
export class GlPromo extends LitElement {
	static override shadowRootOptions: ShadowRootInit = {
		...LitElement.shadowRootOptions,
		delegatesFocus: true,
	};

	static override styles = [
		css`
			:host {
				display: block;
			}

			.promo {
				margin: 0;
				margin-top: var(--gl-space-8);
				text-align: center;
			}

			.header {
				margin-right: var(--gl-space-4);
			}

			.content {
				font-size: smaller;
			}

			.muted {
				opacity: 0.7;
			}

			.link {
				display: block;
				max-width: 100%;
				overflow: hidden;
				text-overflow: ellipsis;
				color: inherit;
				text-align: center;
				white-space: nowrap;
				text-decoration: none;
			}

			.link:focus-visible {
				${focusOutline}
			}

			.link:hover {
				color: inherit;
				text-decoration: underline;
			}
		`,
	];

	@query('a,button,[tabindex="0"]')
	private _focusable?: HTMLElement;

	@property({ type: Object })
	promoPromise: Promise<Promo | undefined> | undefined;

	@property({ type: Object })
	source?: Source;

	@property({ reflect: true, type: String })
	type: 'icon' | 'info' | 'link' = 'info';

	private _hasPromo = false;
	@property({ type: Boolean, reflect: true, attribute: 'has-promo' })
	get hasPromo() {
		return this._hasPromo;
	}
	private set hasPromo(value: boolean) {
		this._hasPromo = value;
	}

	override render(): unknown {
		return html`${until(
			this.promoPromise?.then(promo => this.renderPromo(promo)),
			nothing,
		)}`;
	}

	private renderPromo(promo: Promo | undefined) {
		if (!promo?.content?.webview) {
			this.hasPromo = false;
			return;
		}

		const content = promo.content.webview;
		switch (this.type) {
			case 'icon':
				return html`<code-icon icon="star-full" size="16"></code-icon>`;

			case 'info':
				if (content.info) {
					this.hasPromo = true;
					return html`<p class="promo" part="text">${unsafeHTML(content.info.html)}</p>`;
				}
				break;

			case 'link':
				if (content.link) {
					this.hasPromo = true;
					return html`<a
						class="link"
						part="link"
						href="${this.getCommandUrl(promo)}"
						title="${ifDefined(content.link.title)}"
						>${unsafeHTML(content.link.html)}</a
					>`;
				}
				break;
		}

		this.hasPromo = false;
		return nothing;
	}

	private getCommandUrl(promo: Promo | undefined) {
		let command: GlExtensionCommands | undefined;
		if (promo?.content?.webview?.link?.command?.startsWith('command:')) {
			command = promo.content.webview.link.command.substring('command:'.length) as GlExtensionCommands;
		}

		return createCommandLink<Source>(command ?? 'gitlens.plus.upgrade', this.source);
	}

	override focus(): void {
		this._focusable?.focus();
	}
}
