import "@github/clipboard-copy-element";
import { css, html, LitElement, TemplateResult } from "lit";
import {
  customElement,
  property,
  query,
  queryAssignedNodes,
  state,
} from "lit/decorators.js";

@customElement("permalink-edit")
export class PermalinkEdit extends LitElement {
  @queryAssignedNodes("domain", true)
  _domain!: NodeListOf<HTMLSpanElement>;

  @queryAssignedNodes("slug-input", true)
  _slugInput!: NodeListOf<HTMLInputElement>;

  @query("clipboard-copy")
  _clipboardCopy!: any;

  @property({ attribute: "edit-label" })
  editLabel = "Edit";

  @property({ attribute: "copy-label" })
  copyLabel = "Copy";

  @property({ attribute: "permalink-base" })
  permalinkBase = "";

  @state()
  isEditable = false;

  @state()
  permalink = "";

  @state()
  slugInputEvents = [
    {
      name: "change",
      onEvent: (): void => {
        this.setPermalink();
      },
    },
    {
      name: "focus",
      onEvent: (): void => {
        this.editSlug();
      },
    },
    {
      name: "focusin",
      onEvent: (event: Event): void => {
        setTimeout(() => {
          (event.target as HTMLInputElement).selectionStart = (
            event.target as HTMLInputElement
          ).selectionEnd = 10000;
        }, 0);
      },
    },
    {
      name: "focusout",
      onEvent: (): void => {
        this.stopEdit();
      },
    },
  ];

  connectedCallback(): void {
    super.connectedCallback();
  }

  firstUpdated(): void {
    this.permalinkBase += this.permalinkBase.endsWith("/") ? "" : "/";

    // set permalink value
    this.setPermalink();

    this._clipboardCopy.addEventListener("clipboard-copy", (event: Event) => {
      const notice = (event.target as HTMLDivElement).querySelector(
        ".notice"
      ) as HTMLSpanElement;
      if (notice) {
        notice.hidden = false;
        setTimeout(() => {
          notice.hidden = true;
        }, 1000);
      }
    });

    this._slugInput[0].readOnly = !this.isEditable;
    this.slugInputEvents.forEach((slugInputEvent) => {
      this._slugInput[0].addEventListener(
        slugInputEvent.name,
        slugInputEvent.onEvent
      );
    });
  }

  disconnectedCallback(): void {
    super.disconnectedCallback();

    this.slugInputEvents.forEach((slugInputEvent) => {
      this._slugInput[0].removeEventListener(
        slugInputEvent.name,
        slugInputEvent.onEvent
      );
    });

    this._clipboardCopy.removeEventListener(
      "clipboard-copy",
      (event: Event) => {
        const notice = (event.target as HTMLDivElement).querySelector(
          ".notice"
        ) as HTMLSpanElement;
        if (notice) {
          notice.hidden = false;
          setTimeout(() => {
            notice.hidden = true;
          }, 1000);
        }
      }
    );
  }

  editSlug(): void {
    this.isEditable = true;
    this._slugInput[0].readOnly = !this.isEditable;
    this._slugInput[0].focus();
  }

  stopEdit(): void {
    this.isEditable = false;
    this._slugInput[0].readOnly = !this.isEditable;
  }

  setPermalink(): void {
    this.permalink = this.permalinkBase + this._slugInput[0].value;
  }

  static styles = css`
    ::slotted(input[slot="slug-input"][readonly]) {
      background-color: transparent !important;
      border-color: transparent !important;
      padding-left: 0 !important;
      margin-left: -0.25rem !important;
      font-weight: 600;
    }

    ::slotted([slot="domain"]) {
      margin-right: 0.25rem;
    }

    button,
    clipboard-copy {
      background: transparent;
      border: none;
      padding: 0.25rem;
      cursor: pointer;
    }

    button svg,
    clipboard-copy svg {
      fill: hsl(var(--color-text-base));
      opacity: 0.6;
      font-size: 1.25rem;
    }

    button:hover svg,
    clipboard-copy:hover svg {
      opacity: 1;
    }

    clipboard-copy {
      position: relative;
    }

    .notice {
      position: absolute;
      background-color: black;
      color: #ffffff;
      bottom: -1rem;
      right: 0;
      font-size: 0.75rem;
      padding: 0 0.25rem;
    }
  `;

  render(): TemplateResult<1> {
    return html`<slot name="domain"></slot><slot name="slug-input"></slot>${this
        .isEditable
        ? ""
        : html`<button @click="${this.editSlug}" title="${this.editLabel}">
            <svg
              viewBox="0 0 24 24"
              fill="currentColor"
              width="1em"
              height="1em"
            >
              <g>
                <path fill="none" d="M0 0h24v24H0z" />
                <path
                  d="M7.243 18H3v-4.243L14.435 2.322a1 1 0 0 1 1.414 0l2.829 2.829a1 1 0 0 1 0 1.414L7.243 18zM3 20h18v2H3v-2z"
                />
              </g>
            </svg>
          </button> `}<clipboard-copy
        .value="${this.permalink}"
        title="${this.copyLabel}"
        ><svg viewBox="0 0 24 24" fill="currentColor" width="1em" height="1em">
          <g>
            <path fill="none" d="M0 0h24v24H0z" />
            <path
              d="M6 4v4h12V4h2.007c.548 0 .993.445.993.993v16.014a.994.994 0 0 1-.993.993H3.993A.994.994 0 0 1 3 21.007V4.993C3 4.445 3.445 4 3.993 4H6zm2-2h8v4H8V2z"
            />
          </g>
        </svg>
        <span class="notice" hidden>Copied!</span></clipboard-copy
      >`;
  }
}