import * as plugins from '../plugins.js';
import { apiService, type IMongoIndex } from '../services/index.js';
import { themeStyles } from '../styles/index.js';

const { html, css, cssManager, customElement, property, state, DeesElement } = plugins;

@customElement('tsview-mongo-indexes')
export class TsviewMongoIndexes extends DeesElement {
  @property({ type: String })
  public accessor databaseName: string = '';

  @property({ type: String })
  public accessor collectionName: string = '';

  @state()
  private accessor indexes: IMongoIndex[] = [];

  @state()
  private accessor loading: boolean = false;

  @state()
  private accessor showCreateDialog: boolean = false;

  @state()
  private accessor newIndexKeys: string = '';

  @state()
  private accessor newIndexUnique: boolean = false;

  @state()
  private accessor newIndexSparse: boolean = false;

  public static styles = [
    cssManager.defaultStyles,
    themeStyles,
    css`
      :host {
        display: block;
        height: 100%;
        overflow: hidden;
      }

      .indexes-container {
        display: flex;
        flex-direction: column;
        height: 100%;
      }

      .toolbar {
        display: flex;
        justify-content: flex-end;
        padding: 12px;
        border-bottom: 1px solid #333;
      }

      .create-btn {
        padding: 8px 16px;
        background: rgba(34, 197, 94, 0.2);
        border: 1px solid #22c55e;
        color: #4ade80;
        border-radius: 6px;
        cursor: pointer;
        font-size: 13px;
      }

      .create-btn:hover {
        background: rgba(34, 197, 94, 0.3);
      }

      .indexes-list {
        flex: 1;
        overflow-y: auto;
        padding: 12px;
      }

      .index-card {
        background: rgba(0, 0, 0, 0.2);
        border: 1px solid #333;
        border-radius: 8px;
        padding: 16px;
        margin-bottom: 12px;
      }

      .index-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 12px;
      }

      .index-name {
        font-size: 14px;
        font-weight: 500;
        color: #fff;
      }

      .index-badges {
        display: flex;
        gap: 8px;
      }

      .badge {
        font-size: 11px;
        padding: 2px 8px;
        border-radius: 10px;
        background: rgba(255, 255, 255, 0.1);
        color: #888;
      }

      .badge.unique {
        background: rgba(255, 255, 255, 0.1);
        color: #e0e0e0;
      }

      .badge.sparse {
        background: rgba(251, 191, 36, 0.2);
        color: #fbbf24;
      }

      .index-keys {
        font-family: monospace;
        font-size: 12px;
        color: #888;
        background: rgba(0, 0, 0, 0.2);
        padding: 8px 12px;
        border-radius: 4px;
        margin-bottom: 12px;
      }

      .index-actions {
        display: flex;
        justify-content: flex-end;
      }

      .drop-btn {
        padding: 6px 12px;
        background: transparent;
        border: 1px solid #ef4444;
        color: #f87171;
        border-radius: 4px;
        cursor: pointer;
        font-size: 12px;
      }

      .drop-btn:hover {
        background: rgba(239, 68, 68, 0.2);
      }

      .drop-btn:disabled {
        opacity: 0.5;
        cursor: not-allowed;
      }

      .empty-state {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        height: 200px;
        color: #666;
      }

      .loading-state {
        display: flex;
        align-items: center;
        justify-content: center;
        height: 200px;
        color: #888;
      }

      /* Dialog styles */
      .dialog-overlay {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: rgba(0, 0, 0, 0.7);
        display: flex;
        align-items: center;
        justify-content: center;
        z-index: 1000;
      }

      .dialog {
        background: #1e1e1e;
        border: 1px solid #333;
        border-radius: 12px;
        padding: 24px;
        width: 400px;
        max-width: 90%;
      }

      .dialog-title {
        font-size: 16px;
        font-weight: 500;
        margin-bottom: 16px;
      }

      .dialog-field {
        margin-bottom: 16px;
      }

      .dialog-label {
        display: block;
        font-size: 13px;
        color: #888;
        margin-bottom: 6px;
      }

      .dialog-input {
        width: 100%;
        padding: 8px 12px;
        background: rgba(0, 0, 0, 0.3);
        border: 1px solid #444;
        border-radius: 6px;
        color: #fff;
        font-size: 13px;
        font-family: monospace;
      }

      .dialog-input:focus {
        outline: none;
        border-color: #404040;
      }

      .dialog-checkbox {
        display: flex;
        align-items: center;
        gap: 8px;
        font-size: 13px;
      }

      .dialog-actions {
        display: flex;
        justify-content: flex-end;
        gap: 8px;
        margin-top: 24px;
      }

      .dialog-btn {
        padding: 8px 16px;
        border-radius: 6px;
        cursor: pointer;
        font-size: 13px;
      }

      .dialog-btn.secondary {
        background: transparent;
        border: 1px solid #444;
        color: #888;
      }

      .dialog-btn.secondary:hover {
        border-color: #666;
        color: #aaa;
      }

      .dialog-btn.primary {
        background: rgba(255, 255, 255, 0.1);
        border: 1px solid #404040;
        color: #e0e0e0;
      }

      .dialog-btn.primary:hover {
        background: rgba(255, 255, 255, 0.15);
      }
    `,
  ];

  async connectedCallback() {
    super.connectedCallback();
    await this.loadIndexes();
  }

  updated(changedProperties: Map<string, unknown>) {
    if (changedProperties.has('databaseName') || changedProperties.has('collectionName')) {
      this.loadIndexes();
    }
  }

  private async loadIndexes() {
    if (!this.databaseName || !this.collectionName) return;

    this.loading = true;
    try {
      this.indexes = await apiService.listIndexes(this.databaseName, this.collectionName);
    } catch (err) {
      console.error('Error loading indexes:', err);
      this.indexes = [];
    }
    this.loading = false;
  }

  private openCreateDialog() {
    this.newIndexKeys = '';
    this.newIndexUnique = false;
    this.newIndexSparse = false;
    this.showCreateDialog = true;
  }

  private closeCreateDialog() {
    this.showCreateDialog = false;
  }

  private async createIndex() {
    try {
      const keys = JSON.parse(this.newIndexKeys);

      await apiService.createIndex(this.databaseName, this.collectionName, keys, {
        unique: this.newIndexUnique,
        sparse: this.newIndexSparse,
      });

      this.closeCreateDialog();
      await this.loadIndexes();
    } catch (err) {
      console.error('Error creating index:', err);
      alert('Invalid JSON or index creation failed');
    }
  }

  private async dropIndex(indexName: string) {
    if (indexName === '_id_') {
      alert('Cannot drop the _id index');
      return;
    }

    if (!confirm(`Drop index "${indexName}"?`)) return;

    try {
      await apiService.dropIndex(this.databaseName, this.collectionName, indexName);
      await this.loadIndexes();
    } catch (err) {
      console.error('Error dropping index:', err);
    }
  }

  private formatKeys(keys: Record<string, number>): string {
    return JSON.stringify(keys);
  }

  render() {
    return html`
      <div class="indexes-container">
        <div class="toolbar">
          <button class="create-btn" @click=${this.openCreateDialog}>+ Create Index</button>
        </div>

        <div class="indexes-list">
          ${this.loading
            ? html`<div class="loading-state">Loading...</div>`
            : this.indexes.length === 0
              ? html`<div class="empty-state">No indexes found</div>`
              : this.indexes.map(
                  (idx) => html`
                    <div class="index-card">
                      <div class="index-header">
                        <span class="index-name">${idx.name}</span>
                        <div class="index-badges">
                          ${idx.unique ? html`<span class="badge unique">unique</span>` : ''}
                          ${idx.sparse ? html`<span class="badge sparse">sparse</span>` : ''}
                        </div>
                      </div>
                      <div class="index-keys">${this.formatKeys(idx.keys)}</div>
                      <div class="index-actions">
                        <button
                          class="drop-btn"
                          ?disabled=${idx.name === '_id_'}
                          @click=${() => this.dropIndex(idx.name)}
                        >
                          Drop
                        </button>
                      </div>
                    </div>
                  `
                )}
        </div>
      </div>

      ${this.showCreateDialog
        ? html`
            <div class="dialog-overlay" @click=${this.closeCreateDialog}>
              <div class="dialog" @click=${(e: Event) => e.stopPropagation()}>
                <div class="dialog-title">Create Index</div>

                <div class="dialog-field">
                  <label class="dialog-label">Index Keys (JSON)</label>
                  <input
                    type="text"
                    class="dialog-input"
                    placeholder='{"field": 1}'
                    .value=${this.newIndexKeys}
                    @input=${(e: Event) => (this.newIndexKeys = (e.target as HTMLInputElement).value)}
                  />
                </div>

                <div class="dialog-field">
                  <label class="dialog-checkbox">
                    <input
                      type="checkbox"
                      .checked=${this.newIndexUnique}
                      @change=${(e: Event) => (this.newIndexUnique = (e.target as HTMLInputElement).checked)}
                    />
                    Unique
                  </label>
                </div>

                <div class="dialog-field">
                  <label class="dialog-checkbox">
                    <input
                      type="checkbox"
                      .checked=${this.newIndexSparse}
                      @change=${(e: Event) => (this.newIndexSparse = (e.target as HTMLInputElement).checked)}
                    />
                    Sparse
                  </label>
                </div>

                <div class="dialog-actions">
                  <button class="dialog-btn secondary" @click=${this.closeCreateDialog}>Cancel</button>
                  <button class="dialog-btn primary" @click=${this.createIndex}>Create</button>
                </div>
              </div>
            </div>
          `
        : ''}
    `;
  }
}
