# API Reference

This page provides the complete API reference for the Oops Widget, including types and custom component creation.

## createOopsWidget

Creates and returns a widget instance.

```typescript
function createOopsWidget(config: OopsWidgetConfig): OopsWidgetInstance;
```

### Returns: OopsWidgetInstance

| Method                   | Description                                         |
| ------------------------ | --------------------------------------------------- |
| `start(): Promise<void>` | Performs initial status check and starts monitoring |
| `destroy(): void`        | Stops monitoring and cleans up all resources        |

### Example

```typescript
const widget = createOopsWidget({
  statusUrl: 'YOUR_STATUS_URL_FROM_CONSOLE',
  alertComponent: StatusAlert,
  i18nProvider: createAutoDetectI18nProvider(),
});

// Start the widget
await widget.start();

// Later, when cleaning up
widget.destroy();
```

---

## Interceptors

Both `FetchInterceptor` and `XHRInterceptor` implement the `Interceptor` interface:

```typescript
interface Interceptor {
  name: string;
  setup(): () => void; // Returns cleanup function
}
```

### FetchInterceptor

Monitors all `fetch()` API calls:

```typescript
import { FetchInterceptor } from '@upreport/oops-widget/fetchInterceptor';

const interceptor = new FetchInterceptor({
  timeoutMs: 20000,
  showSlowRequestAlerts: true,
  showErrorAlerts: true,
  monitoredServicePatterns: ['/api/*'],
});
```

### XHRInterceptor

Monitors all `XMLHttpRequest` calls:

```typescript
import { XHRInterceptor } from '@upreport/oops-widget/xhrInterceptor';

const interceptor = new XHRInterceptor({
  timeoutMs: 20000,
  showSlowRequestAlerts: true,
  showErrorAlerts: true,
  monitoredServicePatterns: ['/api/*'],
});
```

---

## Types

### SystemStatus

Represents the possible system statuses:

```typescript
enum SystemStatus {
  Operational = 'Operational',
  DegradedPerformance = 'DegradedPerformance',
  PartialOutage = 'PartialOutage',
  MajorOutage = 'MajorOutage',
  UnderMaintenance = 'UnderMaintenance',
}
```

### SystemStatusResponse

Response from the status endpoint:

```typescript
interface SystemStatusResponse {
  status: SystemStatus;
  incident?: IncidentInfo;
  rawData: Record<string, string>;
}
```

### LogLevel

Logging verbosity levels:

```typescript
enum LogLevel {
  DEBUG = 0,
  INFO = 1,
  WARN = 2,
  ERROR = 3,
  NONE = 4,
}
```

### I18nProvider

Interface for internationalization providers:

```typescript
interface I18nProvider {
  getStatusDetails(status: SystemStatus): Promise<StatusDetails>;
}

interface StatusDetails {
  title: string;
  message: string;
}
```

### OopsWidgetConfig

Full configuration interface:

```typescript
interface OopsWidgetConfig {
  statusUrl: string;
  alertComponent: CustomElementConstructor;
  i18nProvider: I18nProvider;
  placement?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
  interceptors?: Interceptor[];
  mobile?: {
    enabled: boolean;
    placement?: 'top' | 'bottom';
    mediaQuery?: string;
  };
  logLevel?: LogLevel;
  alertClosureBehavior?: Partial<
    Record<
      SystemStatus,
      {
        closeDurationMs?: number;
        checkIntervalMs?: number;
      }
    >
  >;
  displayIncidentDetails?: boolean;
  useSandboxedFetch?: boolean;
}
```

### InterceptorConfig

Configuration for request interceptors:

```typescript
interface InterceptorConfig {
  timeoutMs?: number;
  showSlowRequestAlerts?: boolean;
  showErrorAlerts?: boolean;
  monitoredServicePatterns?: string[];
  monitoredServiceOptions?: {
    requireExplicitPatterns?: boolean;
    includeCurrentOrigin?: boolean;
    treatRelativeAsInternal?: boolean;
  };
}
```

---

## Custom Alert Components

You can replace the built-in `StatusAlert` with your own Web Component implementation.

### Requirements

Custom alert components must:

1. Be implemented as a Web Component (Custom Element)
2. Handle the required attributes
3. Dispatch and listen for widget events

### Observed Attributes

Your component should observe these attributes:

| Attribute                  | Description                                   |
| -------------------------- | --------------------------------------------- |
| `status-type`              | Current system status (e.g., `'MajorOutage'`) |
| `title`                    | Alert title text                              |
| `message`                  | Alert message text                            |
| `placement`                | Position on screen                            |
| `mobile-enabled`           | Whether mobile mode is enabled                |
| `mobile-placement`         | Mobile-specific placement                     |
| `progress-duration`        | Timer duration for progress animation         |
| `incident-names`           | JSON string of incident names                 |
| `incident-statuses`        | JSON string of incident statuses              |
| `incident-links`           | JSON string of incident detail links          |
| `display-incident-details` | Whether to show incident details              |
| `close-button-label`       | Accessibility label for close button          |

### Event Communication

| Event                      | Direction    | Description                                                  |
| -------------------------- | ------------ | ------------------------------------------------------------ |
| `oops-widget-closed`       | Alert → Core | Dispatched when user clicks close button                     |
| `oops-widget-timer-start`  | Core → Alert | Sent when alert timer starts (includes `duration` in detail) |
| `oops-widget-timer-cancel` | Core → Alert | Sent when timer is cancelled                                 |

### Implementation Example

```typescript
class MyCustomAlert extends HTMLElement {
  private shadow: ShadowRoot;

  constructor() {
    super();
    this.shadow = this.attachShadow({ mode: 'open' });
  }

  static get observedAttributes(): string[] {
    return [
      'status-type',
      'title',
      'message',
      'placement',
      'close-button-label',
    ];
  }

  connectedCallback(): void {
    this.render();
    this.setupEvents();
  }

  attributeChangedCallback(): void {
    this.render();
  }

  private setupEvents(): void {
    // Handle close button click
    const closeBtn = this.shadow.querySelector('.close-btn');
    if (closeBtn) {
      closeBtn.addEventListener('click', () => {
        this.dispatchEvent(
          new CustomEvent('oops-widget-closed', {
            bubbles: true,
            composed: true,
          })
        );
      });
    }

    // Handle timer events
    this.addEventListener('oops-widget-timer-start', (e: Event) => {
      const { duration } = (e as CustomEvent<{ duration: number }>).detail;
      const progress = this.shadow.querySelector('.progress-bar');
      if (progress instanceof HTMLElement) {
        progress.style.transition = `width ${duration}ms linear`;
        progress.style.width = '100%';
      }
    });

    this.addEventListener('oops-widget-timer-cancel', () => {
      const progress = this.shadow.querySelector('.progress-bar');
      if (progress instanceof HTMLElement) {
        progress.style.transition = 'none';
        progress.style.width = '0';
      }
    });
  }

  private render(): void {
    const status = this.getAttribute('status-type') || 'DegradedPerformance';
    const title = this.getAttribute('title') || 'Status Alert';
    const message = this.getAttribute('message') || '';
    const closeLabel = this.getAttribute('close-button-label') || 'Close';

    const colors: Record<string, string> = {
      MajorOutage: '#f8d7da',
      PartialOutage: '#ffebd6',
      DegradedPerformance: '#fff3cd',
      UnderMaintenance: '#e7f1fc',
      Operational: '#d4edda',
    };

    const bgColor = colors[status] || colors.DegradedPerformance;

    this.shadow.innerHTML = `
      <style>
        .alert {
          background: ${bgColor};
          padding: 16px;
          border-radius: 8px;
          position: relative;
          overflow: hidden;
          font-family: system-ui, sans-serif;
        }
        .header {
          display: flex;
          justify-content: space-between;
          align-items: center;
        }
        .close-btn {
          background: none;
          border: none;
          cursor: pointer;
          font-size: 18px;
          padding: 4px 8px;
        }
        .progress-bar {
          position: absolute;
          bottom: 0;
          left: 0;
          height: 3px;
          width: 0;
          background: rgba(0,0,0,0.2);
        }
      </style>
      <div class="alert">
        <div class="header">
          <strong>${title}</strong>
          <button class="close-btn" aria-label="${closeLabel}">×</button>
        </div>
        <p>${message}</p>
        <div class="progress-bar"></div>
      </div>
    `;
  }
}

// Register the custom element
customElements.define('my-custom-alert', MyCustomAlert);

// Use in widget configuration
const widget = createOopsWidget({
  statusUrl: 'YOUR_STATUS_URL_FROM_CONSOLE',
  alertComponent: MyCustomAlert,
  i18nProvider: createAutoDetectI18nProvider(),
});
```

---

## Imports Reference

All available imports from the package:

```typescript
// Main exports
import {
  createOopsWidget,
  LogLevel,
  SystemStatus,
} from '@upreport/oops-widget';

// Alert component
import { StatusAlert } from '@upreport/oops-widget/statusAlert';

// Interceptors
import { FetchInterceptor } from '@upreport/oops-widget/fetchInterceptor';
import { XHRInterceptor } from '@upreport/oops-widget/xhrInterceptor';

// i18n providers
import {
  createAutoDetectI18nProvider,
  createStaticI18nProvider,
} from '@upreport/oops-widget/i18n';

// Types (TypeScript)
import type {
  OopsWidgetConfig,
  OopsWidgetInstance,
  InterceptorConfig,
  Interceptor,
  I18nProvider,
  StatusDetails,
  SystemStatusResponse,
} from '@upreport/oops-widget';
```