import { LitElement, html, css, unsafeCSS } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { router } from '../../router';
import { getFlowExecutions } from '../../api';
import { AuthedElement } from '../../api';
import { unifiedWebSocketManager } from '../../services/unified-websocket-manager';
import '@shoelace-style/shoelace/dist/components/badge/badge.js';
import '@shoelace-style/shoelace/dist/components/button/button.js';
import '@shoelace-style/shoelace/dist/components/icon/icon.js';
import '@shoelace-style/shoelace/dist/components/select/select.js';
import '@shoelace-style/shoelace/dist/components/option/option.js';
import { parseUTCDate, formatLocalDateTime } from '../../utils/date';
import consoleStyles from '../../styles/console-styles.css?inline';
import '../../components/view-header.ts';

interface FlowExecution {
  id: string;
  flow_id: string;
  flow_name?: string;
  status: string;
  start_time: string;
  end_time?: string;
  tool_calls_count?: number;
}

@customElement('flow-executions-view')
export class FlowExecutionsView extends AuthedElement {
  static styles = [
    unsafeCSS(consoleStyles),
    css`
      :host {
        display: block;
      }
      .table-wrapper {
        overflow-x: auto;
        margin-top: 1rem;
      }
      table {
        width: 100%;
        border-collapse: collapse;
        min-width: 800px;
      }
      th,
      td {
        border: 1px solid var(--sl-color-neutral-200);
        padding: 8px;
        text-align: left;
      }
      th {
        background-color: var(--sl-color-neutral-100);
      }
      .status-cell {
        display: flex;
        align-items: center;
        gap: 8px;
      }
      .status-indicator {
        width: 8px;
        height: 8px;
        border-radius: 50%;
        animation: pulse 2s infinite;
      }
      .status-indicator.running {
        background-color: var(--sl-color-primary-600);
      }
      .status-indicator.pending {
        background-color: var(--sl-color-warning-600);
      }
      @keyframes pulse {
        0%,
        100% {
          opacity: 1;
        }
        50% {
          opacity: 0.5;
        }
      }
      .header-controls {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 16px;
      }
      .connection-status {
        display: flex;
        align-items: center;
        gap: 8px;
        font-size: 0.9rem;
        color: var(--sl-color-neutral-600);
      }
      .connection-dot {
        width: 8px;
        height: 8px;
        border-radius: 50%;
        background-color: var(--sl-color-success-600);
      }
      .connection-dot.disconnected {
        background-color: var(--sl-color-danger-600);
      }
    `,
  ];

  @state()
  private executions: FlowExecution[] = [];

  @state()
  private wsConnected = false;

  @state()
  private statusFilter = 'all';

  @state()
  private currentPage = 1;

  @state()
  private pageSize = 20;

  @state()
  private hasNextPage = false;

  private unsubscribe?: () => void;

  async connectedCallback() {
    super.connectedCallback();
    await this.loadExecutions();
    this.connectWebSocket();
  }

  async loadExecutions() {
    const rows = await getFlowExecutions({
      limit: this.pageSize + 1,
      skip: (this.currentPage - 1) * this.pageSize,
      status: this.statusFilter === 'all' ? undefined : this.statusFilter,
    });
    this.hasNextPage = rows.length > this.pageSize;
    this.executions = rows.slice(0, this.pageSize);
  }

  get filteredExecutions(): FlowExecution[] {
    return this.executions;
  }

  get paginatedExecutions(): FlowExecution[] {
    return this.filteredExecutions;
  }

  handleStatusFilterChange(event: Event) {
    const select = event.target as any;
    this.statusFilter = select.value;
    this.currentPage = 1; // Reset to first page when filter changes
    void this.loadExecutions();
  }

  nextPage() {
    if (this.hasNextPage) {
      this.currentPage++;
      void this.loadExecutions();
    }
  }

  prevPage() {
    if (this.currentPage > 1) {
      this.currentPage--;
      void this.loadExecutions();
    }
  }

  connectWebSocket() {
    // Subscribe to flow execution updates through unified WebSocket
    this.unsubscribe = unifiedWebSocketManager.subscribe(
      'flow_executions',
      (message: any) => this.handleWebSocketMessage(message)
    );

    // Track connection state
    unifiedWebSocketManager.onStateChange((state) => {
      this.wsConnected = state === 'connected';
      console.log(`Flow executions WebSocket state: ${state}`);
    });
  }

  handleWebSocketMessage(message: any) {
    console.log('Flow updates message:', message);

    // Handle status updates
    if (message.type === 'status_update' && message.execution_id) {
      const executionIndex = this.executions.findIndex(
        (exec) => exec.id === message.execution_id
      );

      if (executionIndex >= 0) {
        // Update existing execution
        const updated = [...this.executions];
        updated[executionIndex] = {
          ...updated[executionIndex],
          status: message.payload.status,
          ...(message.payload.end_time && {
            end_time: message.payload.end_time,
          }),
        };
        // Maintain sort order after update
        this.executions = updated.sort(
          (a, b) =>
            parseUTCDate(b.start_time).getTime() -
            parseUTCDate(a.start_time).getTime()
        );
      } else {
        // New execution started, reload the list
        this.loadExecutions();
      }
    }

    // Handle new executions
    if (message.type === 'execution_started' && message.payload) {
      this.loadExecutions();
    }
  }

  disconnectedCallback() {
    super.disconnectedCallback();
    // Unsubscribe from flow execution updates
    this.unsubscribe?.();
  }

  render() {
    return html`
      <view-header headerText="Flow Executions" width="wide"></view-header>
      <div class="column-layout wide">
        <div class="main-column">
          <div class="header-controls">
            <div style="display: flex; gap: 12px; align-items: center;">
              <sl-select
                size="small"
                value=${this.statusFilter}
                @sl-change=${this.handleStatusFilterChange}
                style="width: 150px;"
              >
                <sl-option value="all">All Status</sl-option>
                <sl-option value="PENDING">Pending</sl-option>
                <sl-option value="RUNNING">Running</sl-option>
                <sl-option value="SUCCEEDED">Succeeded</sl-option>
                <sl-option value="FAILED">Failed</sl-option>
                <sl-option value="CANCELLED">Cancelled</sl-option>
              </sl-select>
              <sl-button size="small" @click=${this.loadExecutions}>
                <sl-icon name="arrow-clockwise"></sl-icon>
                Refresh
              </sl-button>
            </div>
            <div class="connection-status">
              <div
                class="connection-dot ${this.wsConnected ? '' : 'disconnected'}"
              ></div>
              <span>${this.wsConnected ? 'Live Updates' : 'Disconnected'}</span>
            </div>
          </div>

          ${this.paginatedExecutions.length === 0
            ? html`
                <div
                  style="text-align: center; padding: 40px; color: var(--sl-color-neutral-600);"
                >
                  <sl-icon name="inbox" style="font-size: 3rem;"></sl-icon>
                  <p>No executions found.</p>
                </div>
              `
            : html`
                <div
                  style="margin-bottom: 12px; color: var(--sl-color-neutral-600); font-size: 0.9rem;"
                >
                  Showing ${(this.currentPage - 1) * this.pageSize + 1} -
                  ${(this.currentPage - 1) * this.pageSize +
                  this.paginatedExecutions.length}
                  executions
                </div>

                <div class="table-wrapper">
                  <table>
                    <thead>
                      <tr>
                        <th>Flow Name</th>
                        <th>Execution ID</th>
                        <th>Status</th>
                        <th>Start Time</th>
                        <th>End Time</th>
                        <th>Actions</th>
                        <th>Details</th>
                      </tr>
                    </thead>
                    <tbody>
                      ${this.paginatedExecutions.map(
                        (exec) => html`
                          <tr>
                            <td>${exec.flow_name || 'Unnamed Flow'}</td>
                            <td>${exec.id.slice(0, 8)}...</td>
                            <td>
                              <div class="status-cell">
                                ${exec.status === 'RUNNING' ||
                                exec.status === 'PENDING'
                                  ? html`
                                      <div
                                        class="status-indicator ${exec.status.toLowerCase()}"
                                      ></div>
                                    `
                                  : ''}
                                <sl-badge
                                  variant=${this.getStatusVariant(exec.status)}
                                  >${exec.status}</sl-badge
                                >
                              </div>
                            </td>
                            <td>${formatLocalDateTime(exec.start_time)}</td>
                            <td>
                              ${exec.end_time
                                ? formatLocalDateTime(exec.end_time)
                                : '-'}
                            </td>
                            <td>${exec.tool_calls_count || 0}</td>
                            <td>
                              <sl-button
                                size="small"
                                href=${router.urlForPath(
                                  `/console/flows/executions/${exec.id}`
                                )}
                              >
                                <sl-icon name="eye"></sl-icon>
                                View
                              </sl-button>
                            </td>
                          </tr>
                        `
                      )}
                    </tbody>
                  </table>
                </div>

                ${this.currentPage > 1 || this.hasNextPage
                  ? html`
                      <div
                        style="display: flex; justify-content: space-between; align-items: center; margin-top: 16px; padding: 12px; background: var(--sl-color-neutral-50); border-radius: 4px;"
                      >
                        <sl-button
                          size="small"
                          @click=${this.prevPage}
                          ?disabled=${this.currentPage === 1}
                        >
                          <sl-icon name="chevron-left"></sl-icon>
                          Previous
                        </sl-button>
                        <div style="color: var(--sl-color-neutral-700);">
                          Page ${this.currentPage}
                        </div>
                        <sl-button
                          size="small"
                          @click=${this.nextPage}
                          ?disabled=${!this.hasNextPage}
                        >
                          Next
                          <sl-icon name="chevron-right"></sl-icon>
                        </sl-button>
                      </div>
                    `
                  : ''}
              `}
        </div>
      </div>
    `;
  }

  getStatusVariant(status: string) {
    switch (status) {
      case 'SUCCEEDED':
        return 'success';
      case 'FAILED':
        return 'danger';
      case 'RUNNING':
        return 'primary';
      default:
        return 'neutral';
    }
  }
}
