import { WA_IS_MOBILE } from '@ng-web-apis/platform'
import {
  ChangeDetectionStrategy,
  Component,
  inject,
  input,
  signal,
} from '@angular/core'
import { CopyService, DialogService, i18nPipe } from '@start9labs/shared'
import { T } from '@start9labs/start-sdk'
import { TuiButton, TuiDataList, TuiDropdown, TuiInput } from '@taiga-ui/core'
import { PolymorpheusComponent } from '@taiga-ui/polymorpheus'
import { PlaceholderComponent } from 'src/app/routes/portal/components/placeholder.component'
import { TableComponent } from 'src/app/routes/portal/components/table.component'
import { QRModal } from 'src/app/routes/portal/modals/qr.component'
import { ActionService } from 'src/app/services/action.service'
import {
  MappedServiceInterface,
  PluginAddress,
  PluginAddressGroup,
} from '../interface.service'

@Component({
  selector: 'section[pluginGroup]',
  template: `
    <header>
      @if (pluginGroup().pluginPkgInfo; as pkgInfo) {
        <img [src]="pkgInfo.icon" alt="" class="plugin-icon" />
      }
      {{ 'Plugin' | i18n }}: {{ pluginGroup().pluginName }}
      @if (pluginGroup().tableAction; as action) {
        <button
          tuiButton
          iconStart="@tui.plus"
          [style.margin-inline-start]="'auto'"
          (click)="runTableAction()"
        >
          {{ action.metadata.name }}
        </button>
      }
    </header>
    <table [appTable]="['Protocol', 'URL', null]">
      @for (address of pluginGroup().addresses; track $index; let i = $index) {
        <tr>
          <td>{{ address.hostnameInfo.ssl ? 'HTTPS' : 'HTTP' }}</td>
          <td [style.grid-area]="'2 / 1 / 2 / 2'">
            <span class="url">{{ address.url }}</span>
          </td>
          <td [style.width.rem]="5">
            <div class="desktop">
              @if (address.hostnameInfo.metadata.kind === 'plugin') {
                @if (address.hostnameInfo.metadata.removeAction) {
                  @if (
                    pluginGroup().pluginActions[
                      address.hostnameInfo.metadata.removeAction
                    ];
                    as meta
                  ) {
                    <button
                      tuiIconButton
                      appearance="flat-grayscale"
                      iconStart="@tui.trash"
                      (click)="
                        runRowAction(
                          address.hostnameInfo.metadata.removeAction,
                          meta,
                          address
                        )
                      "
                    >
                      {{ meta.name }}
                    </button>
                  }
                }
              }
              <button
                tuiIconButton
                appearance="flat-grayscale"
                iconStart="@tui.qr-code"
                (click)="showQR(address.url)"
              >
                {{ 'Show QR' | i18n }}
              </button>
              <button
                tuiIconButton
                appearance="flat-grayscale"
                iconStart="@tui.copy"
                (click)="copyService.copy(address.url)"
              >
                {{ 'Copy URL' | i18n }}
              </button>
              @if (address.hostnameInfo.metadata.kind === 'plugin') {
                @if (address.hostnameInfo.metadata.overflowActions.length) {
                  <button
                    tuiIconButton
                    tuiDropdown
                    appearance="flat-grayscale"
                    iconStart="@tui.ellipsis-vertical"
                    [tuiAppearanceState]="overflowOpen() === i ? 'hover' : null"
                    [tuiDropdownOpen]="overflowOpen() === i"
                    (tuiDropdownOpenChange)="
                      overflowOpen.set($event ? i : null)
                    "
                  >
                    {{ 'More' | i18n }}
                    <tui-data-list
                      *tuiDropdown
                      (click)="overflowOpen.set(null)"
                    >
                      @for (
                        actionId of address.hostnameInfo.metadata
                          .overflowActions;
                        track actionId
                      ) {
                        @if (pluginGroup().pluginActions[actionId]; as meta) {
                          <button
                            tuiOption
                            (click)="runRowAction(actionId, meta, address)"
                          >
                            {{ meta.name }}
                          </button>
                        }
                      }
                    </tui-data-list>
                  </button>
                }
              }
            </div>
            <div class="mobile">
              <button
                tuiDropdown
                tuiIconButton
                appearance="flat-grayscale"
                iconStart="@tui.ellipsis-vertical"
                [tuiAppearanceState]="open() ? 'hover' : null"
                [(tuiDropdownOpen)]="open"
              >
                {{ 'Actions' | i18n }}
                <tui-data-list *tuiDropdown (click)="open.set(false)">
                  @if (address.hostnameInfo.metadata.kind === 'plugin') {
                    @if (address.hostnameInfo.metadata.removeAction) {
                      @if (
                        pluginGroup().pluginActions[
                          address.hostnameInfo.metadata.removeAction
                        ];
                        as meta
                      ) {
                        <button
                          tuiOption
                          iconStart="@tui.trash"
                          (click)="
                            runRowAction(
                              address.hostnameInfo.metadata.removeAction,
                              meta,
                              address
                            )
                          "
                        >
                          {{ meta.name }}
                        </button>
                      }
                    }
                  }
                  <button
                    tuiOption
                    iconStart="@tui.qr-code"
                    (click)="showQR(address.url)"
                  >
                    {{ 'Show QR' | i18n }}
                  </button>
                  <button
                    tuiOption
                    iconStart="@tui.copy"
                    (click)="copyService.copy(address.url)"
                  >
                    {{ 'Copy URL' | i18n }}
                  </button>
                  @if (address.hostnameInfo.metadata.kind === 'plugin') {
                    @for (
                      actionId of address.hostnameInfo.metadata.overflowActions;
                      track actionId
                    ) {
                      @if (pluginGroup().pluginActions[actionId]; as meta) {
                        <button
                          tuiOption
                          (click)="runRowAction(actionId, meta, address)"
                        >
                          {{ meta.name }}
                        </button>
                      }
                    }
                  }
                </tui-data-list>
              </button>
            </div>
          </td>
        </tr>
      } @empty {
        <tr>
          <td colspan="3">
            <app-placeholder icon="@tui.list-x">
              {{ 'No addresses' | i18n }}
            </app-placeholder>
          </td>
        </tr>
      }
    </table>
  `,
  styles: `
    .plugin-icon {
      height: 1.25rem;
      margin-inline-end: 0.375rem;
      border-radius: 100%;
    }

    :host ::ng-deep {
      th:first-child {
        width: 5rem;
      }
    }

    .desktop {
      display: flex;
      white-space: nowrap;
    }

    .url {
      white-space: normal;
      word-break: break-all;
      display: -webkit-box;
      -webkit-box-orient: vertical;
      -webkit-line-clamp: 1;
      overflow: hidden;
    }

    .mobile {
      display: none;
    }

    :host-context(tui-root._mobile) {
      .desktop {
        display: none;
      }

      .mobile {
        display: block;
      }

      tr {
        grid-template-columns: 1fr auto;
      }

      td {
        width: auto !important;
        align-content: center;
      }
    }
  `,
  host: { class: 'g-card' },
  imports: [
    TuiButton,
    TuiDropdown,
    TuiDataList,
    TuiInput,
    TableComponent,
    PlaceholderComponent,
    i18nPipe,
  ],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class PluginAddressesComponent {
  private readonly isMobile = inject(WA_IS_MOBILE)
  private readonly dialog = inject(DialogService)
  private readonly actionService = inject(ActionService)
  readonly copyService = inject(CopyService)
  readonly open = signal(false)
  readonly overflowOpen = signal<number | null>(null)

  readonly pluginGroup = input.required<PluginAddressGroup>()
  readonly packageId = input('')
  readonly value = input<MappedServiceInterface | undefined>()

  showQR(data: string) {
    this.dialog
      .openComponent(new PolymorpheusComponent(QRModal), {
        size: 's',
        closable: this.isMobile,
        data,
      })
      .subscribe()
  }

  runTableAction() {
    const group = this.pluginGroup()
    if (!group.tableAction || !group.pluginPkgInfo) return

    const iface = this.value()
    if (!iface) return

    const { addressInfo } = iface

    this.actionService.present({
      pkgInfo: group.pluginPkgInfo,
      actionInfo: group.tableAction,
      prefill: {
        urlPluginMetadata: {
          packageId: this.packageId() || null,
          hostId: addressInfo.hostId,
          interfaceId: iface.id,
          internalPort: addressInfo.internalPort,
        },
      },
    })
  }

  runRowAction(
    actionId: string,
    metadata: T.ActionMetadata,
    address: PluginAddress,
  ) {
    const group = this.pluginGroup()
    if (!group.pluginPkgInfo) return

    const iface = this.value()
    if (!iface) return

    const { hostnameInfo } = address
    const { addressInfo } = iface
    const hostMeta = hostnameInfo.metadata

    if (hostMeta.kind !== 'plugin') return

    this.actionService.present({
      pkgInfo: group.pluginPkgInfo,
      actionInfo: { id: actionId, metadata },
      prefill: {
        urlPluginMetadata: {
          packageId: this.packageId() || null,
          hostId: addressInfo.hostId,
          interfaceId: iface.id,
          internalPort: addressInfo.internalPort,
          hostname: hostnameInfo.hostname,
          port: hostnameInfo.port,
          ssl: hostnameInfo.ssl,
          public: hostnameInfo.public,
          info: hostMeta.info,
        },
      },
    })
  }
}
