import formatDateTime from '@/utils/formatDateTime';
import { type LastBlock, getLastBlock } from '@/utils/lastBlock';
import { LitElement, css, html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { when } from 'lit/directives/when.js';
import '@components/LoadingView';
import '@components/General/Tooltip';
import '@components/General/Fieldset';

@customElement('arx-bitcoin-block-widget')
export class BitcoinBlockWidget extends LitElement {
  @state()
  private lastBlock: LastBlock | null = null;

  @state()
  private isLoading = true;

  @state()
  private error: string | null = null;

  private REFRESH_INTERVAL = 30000;

  @state()
  private timer: number | null = null;

  constructor() {
    super();
    this.loadBlock = this.loadBlock.bind(this);
    this.loadBlock();
    this.timer = window.setInterval(this.loadBlock, this.REFRESH_INTERVAL);
  }

  override disconnectedCallback() {
    super.disconnectedCallback();
    if (this.timer) clearInterval(this.timer);
  }

  async loadBlock() {
    this.isLoading = true;
    try {
      const response = await getLastBlock();
      this.lastBlock = response;
      this.error = null;
    } catch (error) {
      this.error = 'Failed to load block data';
      console.error(error);
    } finally {
      this.isLoading = false;
    }
  }

  private formatBlockId(id: string): string {
    if (!id) return '';
    if (id.length <= 16) return id;
    return `${id.substring(0, 8)}...${id.substring(id.length - 8)}`;
  }

  private formatSize(size: number): string {
    if (size < 1024) return `${size} Bytes`;
    if (size < 1024 * 1024) return `${(size / 1024).toFixed(2)} KB`;
    return `${(size / (1024 * 1024)).toFixed(2)} MB`;
  }

  private copyToClipboard(text: string) {
    navigator.clipboard.writeText(text).catch((err) => {
      console.error('Could not copy text: ', err);
    });
  }

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

      .widget-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 12px;
        border-bottom: var(--border) solid var(--color-base-300);
        padding-bottom: 8px;
      }

      .widget-title {
        font-size: 1.2rem;
        font-weight: 600;
        margin: 0;
        color: var(--color-base-content);
        display: flex;
        align-items: center;
        gap: 8px;
      }

      .bitcoin-icon {
        color: var(--color-warning);
        font-size: 1.4rem;
      }

      .error {
        color: var(--color-error-content);
        padding: 12px;
        border-radius: var(--radius-field);
        background: var(--color-error);
        margin-bottom: 12px;
      }
    `,
  ];

  private renderError() {
    return html`<div class="error">${this.error}</div>`;
  }

  private renderLoading() {
    return html`<arx-loading-view></arx-loading-view>`;
  }

  private renderEmptyState() {
    return html`<div class="error">No block data available</div>`;
  }

  private renderBlockData() {
    if (!this.lastBlock) return this.renderEmptyState();

    return html`
      <arx-fieldset legend="Height">
        <strong>${this.lastBlock.height.toLocaleString()}</strong>
      </arx-fieldset>

      <arx-fieldset legend="Block ID">
        <arx-tooltip
          content="Click to copy full ID"
          @click=${() => this.copyToClipboard(this.lastBlock!.id)}
        >
          <strong>${this.formatBlockId(this.lastBlock.id)}</strong>
        </arx-tooltip>
      </arx-fieldset>

      <arx-fieldset legend="Timestamp">
        <strong>${formatDateTime(this.lastBlock.timestamp * 1000)}</strong>
      </arx-fieldset>

      <arx-fieldset legend="Size">
        <strong>
          ${this.formatSize(this.lastBlock.size)}
          (${this.lastBlock.tx_count.toLocaleString()} txs)
        </strong>
      </arx-fieldset>
    `;
  }

  override render() {
    return html`
      <div class="widget-header">
        <h3 class="widget-title">
          <span class="bitcoin-icon">₿</span> Bitcoin Latest Block
        </h3>
      </div>

      ${when(
        this.error,
        () => this.renderError(),
        () =>
          when(
            this.isLoading && !this.lastBlock,
            () => this.renderLoading(),
            () => this.renderBlockData(),
          ),
      )}
    `;
  }
}
