import {
  ChangeDetectionStrategy,
  Component,
  EventEmitter,
  Input,
  OnDestroy,
  Output,
  computed,
  effect,
  inject,
  signal,
} from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { MatIconModule } from '@angular/material/icon';
import { MatButtonModule } from '@angular/material/button';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatTooltipModule } from '@angular/material/tooltip';
import { AgentStatus } from '../../../models/agent.model';
import { LongPressDirective } from '../../../directives/long-press.directive';
import {
  STATUS_COLORS,
  STATUS_LABELS,
  CHANNEL_ICONS,
} from '../../../design/tokens';

// ============================================================================
// AgentCard Component
// Per spec Section 7.3: Composes Agent Status Badge, Task Progress Bar,
// and Quick‑Jump Button into a card with left‑border status accent.
// CUB-26: Emits cardClick and cardLongPress for drawer/modal integration.
// Enhanced with data-status attribute, elapsed time, and design tokens.
// ============================================================================

@Component({
  selector: 'app-agent-card',
  standalone: true,
  imports: [
    CommonModule,
    RouterModule,
    MatIconModule,
    MatButtonModule,
    MatProgressBarModule,
    MatTooltipModule,
    LongPressDirective,
  ],
  templateUrl: './agent-card.component.html',
  styleUrl: './agent-card.component.scss',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AgentCardComponent implements OnDestroy {
  // --- Six required inputs per spec ---

  /** Agent status — drives badge color and left‑border accent */
  @Input({ required: true }) status!: AgentStatus;

  /** Current task description, e.g. "Reviewing PR #42" */
  @Input() task = '';

  /** Task progress percentage 0–100 */
  @Input() progress = 0;

  /** Full session key for quick‑jump navigation */
  @Input({ required: true }) sessionKey = '';

  /** Communication channel, e.g. "telegram" */
  @Input({ required: true }) channel = '';

  /** Timestamp of last agent activity */
  @Input({ required: true }) lastActivity!: Date;

  // --- Additional display inputs ---

  /** Short agent ID, e.g. "otto" */
  @Input() agentId = '';

  /** Display name, e.g. "Otto" */
  @Input() displayName = '';

  /** Role description, e.g. "Orchestrator Agent" */
  @Input() role = '';

  /** Error message (shown only when status is 'error') */
  @Input() errorMessage = '';

  /** Elapsed time string, e.g. "04m 12s" */
  @Input() taskElapsed = '';

  // --- CUB-26: Outputs for drawer/modal integration ---

  /** Emitted when the card is clicked — opens the session drawer. */
  @Output() readonly cardClick = new EventEmitter<string>();

  /** Emitted when the card is long-pressed — bypasses drawer, opens session log directly. */
  @Output() readonly cardLongPress = new EventEmitter<string>();

  // --- Internal state ---

  /** Timer for refreshing relative-time label */
  private _timer: ReturnType<typeof setInterval> | null = null;

  /** Internal signal to trigger relative-time recomputation */
  private readonly _tick = signal(0);

  // --- Computed values using design tokens ---

  /** Map status → CSS custom property for the left‑border accent */
  readonly statusBorderColor = computed(() => {
    const map: Record<AgentStatus, string> = {
      active: 'var(--status-active)',
      idle: 'var(--status-idle)',
      thinking: 'var(--status-thinking)',
      error: 'var(--status-error)',
      offline: 'var(--status-offline)',
    };
    return map[this.status] ?? 'var(--status-offline)';
  });

  /** Human‑readable status label (from design tokens) */
  readonly statusLabel = computed(() => STATUS_LABELS[this.status] ?? this.status);

  /** CSS class suffix for the status badge dot */
  readonly statusDotClass = computed(() => `status-dot--${this.status}`);

  /** Material icon name for the channel (from design tokens) */
  readonly channelIcon = computed(() => CHANNEL_ICONS[this.channel] ?? 'chat');

  /** Relative time string for lastActivity, refreshed every 30s */
  readonly lastActivityLabel = computed(() => {
    // Read tick to create dependency that forces recomputation
    this._tick();
    return this._relativeTime(this.lastActivity);
  });

  /** Quick‑jump route derived from sessionKey */
  readonly jumpRoute = computed(() => `/sessions/${this.sessionKey}`);

  /** Whether progress bar should show */
  readonly showProgress = computed(() => this.progress > 0 && this.status !== 'error');

  /** Whether error state is active */
  readonly isError = computed(() => this.status === 'error');

  /** Whether card is in an active-like state (active or thinking) */
  readonly isActiveLike = computed(() => this.status === 'active' || this.status === 'thinking');

  constructor() {
    // Start the relative-time refresh timer
    this._startTimer();
  }

  ngOnDestroy(): void {
    this._stopTimer();
  }

  // --- Private helpers ---

  private _relativeTime(date: Date | null | undefined): string {
    if (!date) return '';
    const now = Date.now();
    const then = date.getTime();
    const diffSec = Math.max(0, Math.floor((now - then) / 1000));
    if (diffSec < 60) return 'just now';
    if (diffSec < 3600) return `${Math.floor(diffSec / 60)}m ago`;
    if (diffSec < 86400) return `${Math.floor(diffSec / 3600)}h ago`;
    return `${Math.floor(diffSec / 86400)}d ago`;
  }

  private _startTimer(): void {
    this._stopTimer();
    this._timer = setInterval(() => {
      // Increment tick to force lastActivityLabel recomputation
      this._tick.update(v => v + 1);
    }, 30_000);
  }

  private _stopTimer(): void {
    if (this._timer) {
      clearInterval(this._timer);
      this._timer = null;
    }
  }
}