import { LitElement, html, css } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { AuthedElement } from '../../api';
import { unifiedWebSocketManager } from '../../services/unified-websocket-manager';
import '@shoelace-style/shoelace/dist/components/card/card.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/switch/switch.js';
import '@shoelace-style/shoelace/dist/components/select/select.js';
import '@shoelace-style/shoelace/dist/components/option/option.js';
import '@shoelace-style/shoelace/dist/components/badge/badge.js';
import '@shoelace-style/shoelace/dist/components/alert/alert.js';
import '@shoelace-style/shoelace/dist/components/spinner/spinner.js';
import '@shoelace-style/shoelace/dist/components/qr-code/qr-code.js';
import '@shoelace-style/shoelace/dist/components/dialog/dialog.js';

interface NotificationPreferences {
  id: string;
  preferred_channel: string;
  enable_email: boolean;
  enable_mobile_push: boolean;
  mobile_device_tokens?: Array<{
    platform: string;
    token: string;
    registered_at: string;
  }>;
}

interface QRCodeData {
  token: string;
  qr_data: string;
  expires_at: string;
  expires_in_seconds: number;
}

@customElement('notification-preferences-view')
export class NotificationPreferencesView extends AuthedElement {
  @state()
  private preferences: NotificationPreferences | null = null;

  @state()
  private isLoading = true;

  @state()
  private isSaving = false;

  @state()
  private errorMessage = '';

  @state()
  private successMessage = '';

  @state()
  private showQRDialog = false;

  @state()
  private qrCodeData: QRCodeData | null = null;

  @state()
  private qrExpiry: number = 0;

  private qrExpiryInterval: any = null;
  private unsubscribe?: () => void;

  static styles = css`
    :host {
      display: block;
      padding: var(--sl-spacing-large);
      max-width: 900px;
      margin: 0 auto;
    }

    .header {
      margin-bottom: var(--sl-spacing-large);
    }

    .header h1 {
      margin: 0 0 var(--sl-spacing-x-small) 0;
      font-size: var(--sl-font-size-2x-large);
      font-weight: var(--sl-font-weight-semibold);
      color: var(--sl-color-neutral-900);
    }

    .header p {
      margin: 0;
      color: var(--sl-color-neutral-600);
      font-size: var(--sl-font-size-medium);
    }

    .content {
      display: flex;
      flex-direction: column;
      gap: var(--sl-spacing-large);
    }

    .section-title {
      font-size: var(--sl-font-size-large);
      font-weight: var(--sl-font-weight-semibold);
      margin: 0 0 var(--sl-spacing-medium) 0;
      color: var(--sl-color-neutral-900);
    }

    .preference-row {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: var(--sl-spacing-medium);
      border: 1px solid var(--sl-color-neutral-200);
      border-radius: var(--sl-border-radius-medium);
    }

    .preference-label {
      display: flex;
      flex-direction: column;
      gap: var(--sl-spacing-2x-small);
    }

    .preference-title {
      font-weight: var(--sl-font-weight-semibold);
      color: var(--sl-color-neutral-900);
    }

    .preference-description {
      font-size: var(--sl-font-size-small);
      color: var(--sl-color-neutral-600);
    }

    .devices-list {
      display: flex;
      flex-direction: column;
      gap: var(--sl-spacing-small);
    }

    .device-item {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: var(--sl-spacing-medium);
      border: 1px solid var(--sl-color-neutral-200);
      border-radius: var(--sl-border-radius-medium);
      background: var(--sl-color-neutral-50);
    }

    .device-info {
      display: flex;
      align-items: center;
      gap: var(--sl-spacing-medium);
    }

    .device-platform {
      display: flex;
      align-items: center;
      gap: var(--sl-spacing-x-small);
    }

    .device-details {
      display: flex;
      flex-direction: column;
      gap: var(--sl-spacing-2x-small);
    }

    .device-token {
      font-family: var(--sl-font-mono);
      font-size: var(--sl-font-size-x-small);
      color: var(--sl-color-neutral-600);
    }

    .device-date {
      font-size: var(--sl-font-size-x-small);
      color: var(--sl-color-neutral-500);
    }

    .qr-container {
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: var(--sl-spacing-medium);
      padding: var(--sl-spacing-large);
    }

    .qr-code-wrapper {
      padding: var(--sl-spacing-large);
      background: white;
      border-radius: var(--sl-border-radius-medium);
      box-shadow: var(--sl-shadow-large);
    }

    .qr-instructions {
      text-align: center;
      max-width: 400px;
    }

    .qr-instructions h4 {
      margin: 0 0 var(--sl-spacing-small) 0;
      font-size: var(--sl-font-size-large);
      font-weight: var(--sl-font-weight-semibold);
    }

    .qr-instructions p {
      margin: 0;
      color: var(--sl-color-neutral-600);
      line-height: 1.5;
    }

    .qr-expiry {
      font-size: var(--sl-font-size-small);
      color: var(--sl-color-warning-700);
      font-weight: var(--sl-font-weight-semibold);
    }

    .app-store-links {
      display: flex;
      justify-content: center;
      gap: var(--sl-spacing-medium);
      margin-top: var(--sl-spacing-large);
    }

    .app-store-button {
      display: inline-flex;
      align-items: center;
      gap: var(--sl-spacing-small);
      padding: var(--sl-spacing-medium) var(--sl-spacing-large);
      background: var(--sl-color-primary-600);
      color: var(--sl-color-neutral-0);
      text-decoration: none;
      border-radius: var(--sl-border-radius-medium);
      transition: all 0.2s ease;
      font-weight: var(--sl-font-weight-semibold);
      box-shadow: var(--sl-shadow-small);
    }

    .app-store-button:hover {
      background: var(--sl-color-primary-700);
      transform: translateY(-1px);
      box-shadow: var(--sl-shadow-medium);
    }

    .app-store-button sl-icon {
      font-size: 1.5rem;
    }

    .loading {
      display: flex;
      justify-content: center;
      align-items: center;
      min-height: 400px;
    }
  `;

  async connectedCallback() {
    super.connectedCallback();
    await this.loadPreferences();

    // Connect to WebSocket for real-time device registration updates
    try {
      console.debug(
        '[NotificationPrefs] Setting up device_registered subscription'
      );

      this.unsubscribe = unifiedWebSocketManager.subscribe(
        'device_registered',
        (message: any) => {
          console.debug(
            '[NotificationPrefs] Received device_registered event:',
            message
          );

          // Close QR dialog if open
          if (this.showQRDialog) {
            console.debug('[NotificationPrefs] Closing QR dialog');
            this.handleCloseQRDialog();
          }

          // Reload preferences to show new device
          this.loadPreferences();

          // Show success message
          this.successMessage = `${message.platform === 'ios' ? 'iOS' : 'Android'} device registered successfully`;
          setTimeout(() => (this.successMessage = ''), 5000);
        }
      );

      // Track connection state changes
      unifiedWebSocketManager.onStateChange((state) => {
        console.debug('[NotificationPrefs] WebSocket state:', state);
      });

      console.debug('[NotificationPrefs] Subscription setup complete');
    } catch (error) {
      console.error('Failed to setup WebSocket subscription:', error);
    }
  }

  disconnectedCallback() {
    super.disconnectedCallback();
    if (this.qrExpiryInterval) {
      clearInterval(this.qrExpiryInterval);
    }

    // Disconnect from WebSocket
    this.unsubscribe?.();
  }

  private async loadPreferences() {
    try {
      this.isLoading = true;
      const data = await this.fetchData('/api/v1/notification-preferences/me');

      if (!data) {
        throw new Error('Failed to load preferences');
      }

      this.preferences = data;
      this.errorMessage = '';
    } catch (error: any) {
      this.errorMessage =
        error.message || 'Failed to load notification preferences';
    } finally {
      this.isLoading = false;
    }
  }

  private async handleChannelChange(e: any) {
    if (!this.preferences) return;

    try {
      this.isSaving = true;
      const data = await this.fetchData('/api/v1/notification-preferences/me', {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          preferred_channel: e.target.value,
        }),
      });

      if (!data) {
        throw new Error('Failed to update channel preference');
      }

      this.preferences = data;
      this.successMessage = 'Preference updated successfully';
      setTimeout(() => (this.successMessage = ''), 3000);
    } catch (error: any) {
      this.errorMessage = error.message || 'Failed to update preference';
    } finally {
      this.isSaving = false;
    }
  }

  private async handleToggleEmail(e: any) {
    if (!this.preferences) return;

    try {
      this.isSaving = true;
      const data = await this.fetchData('/api/v1/notification-preferences/me', {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          enable_email: e.target.checked,
        }),
      });

      if (!data) {
        throw new Error('Failed to update email preference');
      }

      this.preferences = data;
      this.successMessage = 'Preference updated successfully';
      setTimeout(() => (this.successMessage = ''), 3000);
    } catch (error: any) {
      this.errorMessage = error.message || 'Failed to update preference';
    } finally {
      this.isSaving = false;
    }
  }

  private async handleToggleMobilePush(e: any) {
    if (!this.preferences) return;

    try {
      this.isSaving = true;
      const data = await this.fetchData('/api/v1/notification-preferences/me', {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          enable_mobile_push: e.target.checked,
        }),
      });

      if (!data) {
        throw new Error('Failed to update mobile push preference');
      }

      this.preferences = data;
      this.successMessage = 'Preference updated successfully';
      setTimeout(() => (this.successMessage = ''), 3000);
    } catch (error: any) {
      this.errorMessage = error.message || 'Failed to update preference';
    } finally {
      this.isSaving = false;
    }
  }

  private async handleShowQRCode() {
    try {
      const data = await this.fetchData(
        '/api/v1/notification-preferences/me/qr-code'
      );

      if (!data) {
        throw new Error('Failed to generate QR code');
      }

      this.qrCodeData = data;
      this.qrExpiry = this.qrCodeData!.expires_in_seconds;
      this.showQRDialog = true;

      // Start countdown
      this.qrExpiryInterval = setInterval(() => {
        this.qrExpiry--;
        if (this.qrExpiry <= 0) {
          clearInterval(this.qrExpiryInterval);
          this.handleCloseQRDialog();
        }
      }, 1000);
    } catch (error: any) {
      this.errorMessage = error.message || 'Failed to generate QR code';
    }
  }

  private handleCloseQRDialog() {
    this.showQRDialog = false;
    this.qrCodeData = null;
    if (this.qrExpiryInterval) {
      clearInterval(this.qrExpiryInterval);
      this.qrExpiryInterval = null;
    }
  }

  private async handleUnregisterDevice(token: string) {
    if (!confirm('Are you sure you want to unregister this device?')) {
      return;
    }

    try {
      const data = await this.fetchData(
        `/api/v1/notification-preferences/me/device/${encodeURIComponent(token)}`,
        {
          method: 'DELETE',
        }
      );

      if (!data) {
        throw new Error('Failed to unregister device');
      }

      this.preferences = data;
      this.successMessage = 'Device unregistered successfully';
      setTimeout(() => (this.successMessage = ''), 3000);
    } catch (error: any) {
      this.errorMessage = error.message || 'Failed to unregister device';
    }
  }

  private formatDate(dateString: string): string {
    const date = new Date(dateString);
    return date.toLocaleDateString() + ' ' + date.toLocaleTimeString();
  }

  private formatExpiry(seconds: number): string {
    const minutes = Math.floor(seconds / 60);
    const secs = seconds % 60;
    return `${minutes}:${secs.toString().padStart(2, '0')}`;
  }

  render() {
    if (this.isLoading) {
      return html`
        <div class="loading">
          <sl-spinner style="font-size: 3rem;"></sl-spinner>
        </div>
      `;
    }

    return html`
      <div class="header">
        <h1>Notification Preferences</h1>
        <p>Manage how you receive approval request notifications</p>
      </div>

      ${this.successMessage
        ? html`
            <sl-alert variant="success" open closable>
              <sl-icon slot="icon" name="check-circle"></sl-icon>
              ${this.successMessage}
            </sl-alert>
          `
        : ''}
      ${this.errorMessage
        ? html`
            <sl-alert variant="danger" open closable>
              <sl-icon slot="icon" name="exclamation-triangle"></sl-icon>
              ${this.errorMessage}
            </sl-alert>
          `
        : ''}

      <div class="content">
        <sl-card>
          <h2 class="section-title">Notification Channels</h2>

          <div class="preference-row">
            <div class="preference-label">
              <div class="preference-title">Email Notifications</div>
              <div class="preference-description">
                Receive approval requests via email
              </div>
            </div>
            <sl-switch
              ?checked=${this.preferences?.enable_email}
              @sl-change=${this.handleToggleEmail}
              ?disabled=${this.isSaving}
            ></sl-switch>
          </div>

          <div
            class="preference-row"
            style="margin-top: var(--sl-spacing-small);"
          >
            <div class="preference-label">
              <div class="preference-title">Mobile Push Notifications</div>
              <div class="preference-description">
                Receive approval requests on your mobile device
              </div>
            </div>
            <sl-switch
              ?checked=${this.preferences?.enable_mobile_push}
              @sl-change=${this.handleToggleMobilePush}
              ?disabled=${this.isSaving}
            ></sl-switch>
          </div>
        </sl-card>

        <sl-card>
          <div
            style="display: flex; justify-content: space-between; align-items: center; margin-bottom: var(--sl-spacing-medium);"
          >
            <h2 class="section-title" style="margin: 0;">Mobile Devices</h2>
            <sl-button size="small" @click=${this.handleShowQRCode}>
              <sl-icon slot="prefix" name="qr-code"></sl-icon>
              Register New Device
            </sl-button>
          </div>

          ${this.preferences?.mobile_device_tokens &&
          this.preferences.mobile_device_tokens.length > 0
            ? html`
                <div class="devices-list">
                  ${this.preferences.mobile_device_tokens.map(
                    (device) => html`
                      <div class="device-item">
                        <div class="device-info">
                          <div class="device-platform">
                            <sl-icon
                              name=${device.platform === 'ios'
                                ? 'phone'
                                : 'phone-fill'}
                              style="font-size: 1.5rem;"
                            ></sl-icon>
                            <sl-badge
                              variant=${device.platform === 'ios'
                                ? 'primary'
                                : 'success'}
                            >
                              ${device.platform === 'ios' ? 'iOS' : 'Android'}
                            </sl-badge>
                          </div>
                          <div class="device-details">
                            <div class="device-token">
                              ${device.token.substring(0, 20)}...
                            </div>
                            <div class="device-date">
                              Registered:
                              ${this.formatDate(device.registered_at)}
                            </div>
                          </div>
                        </div>
                        <sl-button
                          size="small"
                          variant="danger"
                          @click=${() =>
                            this.handleUnregisterDevice(device.token)}
                        >
                          <sl-icon slot="prefix" name="trash"></sl-icon>
                          Unregister
                        </sl-button>
                      </div>
                    `
                  )}
                </div>
              `
            : html`
                <div class="empty-state">
                  <sl-icon name="phone"></sl-icon>
                  <p>No mobile devices registered</p>
                  <p
                    style="font-size: var(--sl-font-size-small); margin-top: var(--sl-spacing-small);"
                  >
                    Scan a QR code with your mobile app to register your device
                  </p>
                </div>
              `}
        </sl-card>

        <div class="app-store-links">
          <a
            href="https://apps.apple.com/app/preloop/id6757803021"
            target="_blank"
            rel="noopener noreferrer"
            class="app-store-button"
            title="Download on the App Store"
          >
            <sl-icon name="apple"></sl-icon>
            <span>App Store</span>
          </a>
          <a
            href="https://play.google.com/store/apps/details?id=ai.spacecode.preloop&pli=1"
            target="_blank"
            rel="noopener noreferrer"
            class="app-store-button"
            title="Get it on Google Play"
          >
            <sl-icon name="google-play"></sl-icon>
            <span>Google Play</span>
          </a>
        </div>
      </div>

      <sl-dialog
        label="Register Mobile Device"
        ?open=${this.showQRDialog}
        @sl-request-close=${this.handleCloseQRDialog}
        style="--width: 600px;"
      >
        ${this.qrCodeData
          ? html`
              <div class="qr-container">
                <div class="qr-instructions">
                  <h4>Scan with your mobile app</h4>
                  <p>
                    Open the Preloop mobile app and scan this QR code to
                    register your device for push notifications.
                  </p>
                </div>

                <div class="qr-code-wrapper">
                  <sl-qr-code
                    value=${this.qrCodeData.qr_data}
                    size="300"
                  ></sl-qr-code>
                </div>

                <div class="qr-expiry">
                  <sl-icon name="clock"></sl-icon>
                  Expires in: ${this.formatExpiry(this.qrExpiry)}
                </div>
              </div>
            `
          : html`<sl-spinner></sl-spinner>`}

        <sl-button slot="footer" @click=${this.handleCloseQRDialog}>
          Close
        </sl-button>
      </sl-dialog>
    `;
  }
}
