import { LitElement, html, css } from "lit";
import { customElement, state } from "lit/decorators.js";
import { store, toBlueskyPostUrl, shortPostId, formatTimestamp } from "../store";
import { apiService, blueskyService } from "../services";
import type { FeedItem } from "../types";

@customElement("app-session-page")
export class AppSessionPage extends LitElement {
  @state()
  private isLoading = false;

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

    .dashboard-grid {
      max-width: 800px;
      margin: 0 auto;
    }

    .panel {
      background: var(--panel-bg, #fff);
      border-radius: 0.5rem;
      box-shadow: var(--panel-shadow, 0 1px 3px rgba(0,0,0,0.1));
      padding: 1rem;
    }

    .panel-header {
      margin-bottom: 0.75rem;
      padding-bottom: 0.5rem;
      border-bottom: 1px solid var(--border-color, #e5e7eb);
    }

    .panel-header h1 {
      font-size: 1.25rem;
      margin: 0;
    }

    .eyebrow {
      font-size: 0.6875rem;
      text-transform: uppercase;
      letter-spacing: 0.05em;
      color: var(--text-muted, #6b7280);
      margin-bottom: 0.25rem;
    }

    .lede {
      font-size: 0.8125rem;
      color: var(--text-secondary, #4b5563);
      margin-bottom: 1rem;
      line-height: 1.4;
    }

    .session-actions {
      display: flex;
      flex-wrap: wrap;
      gap: 0.5rem;
      align-items: flex-end;
      margin-bottom: 0.75rem;
    }

    .form-group {
      display: flex;
      flex-direction: column;
      gap: 0.25rem;
      flex: 1;
      min-width: 200px;
    }

    label {
      font-size: 0.8125rem;
      font-weight: 500;
      color: var(--text-primary, #1f2937);
    }

    input[type="text"] {
      padding: 0.375rem 0.5rem;
      border: 1px solid var(--border-color, #d1d5db);
      border-radius: 0.25rem;
      font-size: 0.8125rem;
    }

    input[type="text"]:disabled {
      background: var(--disabled-bg, #f3f4f6);
      cursor: not-allowed;
    }

    button {
      padding: 0.375rem 0.75rem;
      border: none;
      border-radius: 0.25rem;
      font-size: 0.8125rem;
      font-weight: 500;
      cursor: pointer;
      transition: background 0.15s;
      white-space: nowrap;
    }

    button.accent {
      background: var(--accent-bg, #3b82f6);
      color: white;
    }

    button.accent:hover:not(:disabled) {
      background: var(--accent-hover, #2563eb);
    }

    button:disabled {
      opacity: 0.5;
      cursor: not-allowed;
    }

    .session-meta {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: 0.375rem 1rem;
      font-size: 0.6875rem;
      color: var(--text-muted, #6b7280);
      margin-bottom: 0.75rem;
      padding: 0.5rem;
      background: var(--meta-bg, #f9fafb);
      border-radius: 0.25rem;
    }

    .generator-endpoint {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 0.5rem 0.75rem;
      background: var(--endpoint-bg, #f3f4f6);
      border-radius: 0.25rem;
      gap: 1rem;
    }

    .generator-endpoint > div {
      flex: 1;
      min-width: 0;
    }

    .generator-endpoint strong {
      display: block;
      font-size: 0.875rem;
      margin: 0.125rem 0;
    }

    .small-copy {
      font-size: 0.6875rem;
      color: var(--text-muted, #6b7280);
      display: block;
      margin-top: 0.125rem;
    }

    .message-bar {
      padding: 0.5rem 0.75rem;
      border-radius: 0.25rem;
      font-size: 0.8125rem;
      margin-top: 0.75rem;
    }

    .message-bar.error {
      background: var(--error-bg, #fef2f2);
      color: var(--error-text, #991b1b);
      border: 1px solid var(--error-border, #fecaca);
    }

    .message-bar.success {
      background: var(--success-bg, #f0fdf4);
      color: var(--success-text, #166534);
      border: 1px solid var(--success-border, #bbf7d0);
    }
  `;

  connectedCallback() {
    super.connectedCallback();
    this.initialize();
    this.unsubscribe = store.subscribe(() => this.requestUpdate());
  }

  disconnectedCallback() {
    super.disconnectedCallback();
    this.unsubscribe?.();
  }

  private unsubscribe?: () => void;

  async initialize() {
    try {
      const [gens, info] = await Promise.all([
        apiService.getGenerators(),
        apiService.getFeedGeneratorInfo(),
      ]);
      store.setGenerators(gens);
      store.setFeedGeneratorInfo(info);

      const sess = await blueskyService.getSession();
      store.setSession(sess);
      if (sess.isAuthenticated) {
        store.setLoginIdentifier(sess.handle || sess.did || "");
        await this.loadFeedState();
      }
    } catch (err) {
      store.setError(`Bluesky client bootstrap failed: ${err}`);
    }
  }

  async loadFeedState() {
    const did = store.session.did;
    if (!did) return;
    try {
      const likeFeedData = await apiService.getLikeFeed(did);
      store.setLikeFeed({
        importedPostCount: likeFeedData.importedPostCount,
        importedAuthorCount: likeFeedData.importedAuthorCount,
        items: likeFeedData.items,
        authors: likeFeedData.authors,
      });
    } catch (err) {
      console.error("Failed to load feed state:", err);
    }
  }

  async connect() {
    store.setBusy(true);
    store.setError(null);
    try {
      const id = store.loginIdentifier.trim();
      await blueskyService.beginLogin(id);
    } catch (err) {
      store.setError(String(err));
    } finally {
      store.setBusy(false);
    }
  }

  async importFeed() {
    if (!store.isAuthenticated) {
      store.setError("Sign in first.");
      return;
    }

    store.setBusy(true);
    store.setError(null);
    store.setStatus("Crawling your liked network...");

    try {
      const imported = await blueskyService.fetchLikedNetwork();
      const postCount = imported.items?.length ?? 0;
      const authorCount = imported.authors?.length ?? 0;
      store.setStatus(`Crawled ${postCount} posts from ${authorCount} authors. Storing...`);
      await apiService.importFeed(imported);
      await this.loadFeedState();
      store.setStatus(`Imported ${postCount} posts from ${authorCount} authors.`);
    } catch (err) {
      console.error("Import failed:", err);
      store.setError(String(err));
    } finally {
      store.setBusy(false);
    }
  }

  async publishFeed() {
    if (!store.isAuthenticated || !store.feedGeneratorInfo?.serviceDid) {
      store.setError("Sign in first.");
      return;
    }

    store.setBusy(true);
    store.setError(null);
    try {
      const info = store.feedGeneratorInfo;
      await blueskyService.publishFeedGenerator({
        ownerDid: store.session.did!,
        serviceDid: info.serviceDid!,
        feedKey: info.feedKey,
        displayName: info.displayName,
        description: info.description,
      });
      store.setStatus(`Published ${info.feedUri}`);
    } catch (err) {
      store.setError(String(err));
    } finally {
      store.setBusy(false);
    }
  }

  private handleInputChange(e: Event) {
    const target = e.target as HTMLInputElement;
    store.setLoginIdentifier(target.value);
  }

  render() {
    const isConnectDisabled = store.busy || !store.loginIdentifier.trim();
    const isImportDisabled = store.busy || !store.isAuthenticated;
    const isPublishDisabled = store.busy || !store.isAuthenticated || !store.feedGeneratorInfo?.serviceDid;

    return html`
      <div class="dashboard-grid">
        <div class="panel-shell">
          <div class="panel">
            <div class="panel-header">
              <div class="eyebrow">Session</div>
              <h1>Bluesky feed dashboard</h1>
            </div>

            <div class="lede">
              OAuth runs in TypeScript using the official atproto browser SDK, while the backend
              handles feed tuning and the published feed surface.
            </div>

            <div class="session-actions">
              <div class="form-group">
                <label>Bluesky handle</label>
                <input
                  type="text"
                  .value=${store.loginIdentifier}
                  @input=${this.handleInputChange}
                  placeholder="you.bsky.social"
                  ?disabled=${store.busy}
                />
              </div>
              <button class="accent" @click=${this.connect} ?disabled=${isConnectDisabled}>
                ${store.isAuthenticated ? "Reconnect" : "Connect with Bluesky"}
              </button>
              <button class="accent" @click=${this.importFeed} ?disabled=${isImportDisabled}>
                Refresh from likes
              </button>
            </div>

            <div class="session-meta">
              <span>Status: ${store.sessionStatusText}</span>
              <span>PDS: ${store.session.pdsUrl || "not connected"}</span>
              <span>Imported authors: ${store.likeFeed.importedAuthorCount}</span>
              <span>Imported posts: ${store.likeFeed.importedPostCount}</span>
            </div>

            <div class="generator-endpoint">
              <div>
                <div class="eyebrow">Published Feed</div>
                <strong>${store.feedGeneratorInfo?.displayName || "Feed generator"}</strong>
                <span class="small-copy">
                  ${store.feedGeneratorInfo?.isConfigured
                    ? html`<span>${store.feedGeneratorInfo?.feedUri}</span>`
                    : null}
                </span>
                ${store.feedGeneratorInfo?.serviceDid
                  ? html`<span class="small-copy">Service DID: ${store.feedGeneratorInfo.serviceDid}</span>`
                  : null}
              </div>
              <button class="accent" @click=${this.publishFeed} ?disabled=${isPublishDisabled}>
                Publish feed record
              </button>
            </div>

            ${store.error ? html`<div class="message-bar error">${store.error}</div>` : null}
            ${store.status ? html`<div class="message-bar success">${store.status}</div>` : null}
          </div>
        </div>
      </div>
    `;
  }
}
An unhandled error has occurred. Reload 🗙