import { TuiCell } from '@taiga-ui/core'
import { ChangeDetectionStrategy, Component, inject } from '@angular/core'
import { toSignal } from '@angular/core/rxjs-interop'
import {
  CopyService,
  DialogService,
  getPkgId,
  i18nKey,
  i18nPipe,
  MARKDOWN,
} from '@start9labs/shared'
import { PatchDB } from 'patch-db-client'
import { defer, map } from 'rxjs'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { DataModel } from 'src/app/services/patch-db/data-model'
import { getManifest } from 'src/app/utils/get-package-data'
import {
  AdditionalItem,
  NOT_PROVIDED,
  ServiceAdditionalItemComponent,
} from '../components/additional-item.component'

@Component({
  template: `
    @for (group of groups(); track $index) {
      <section class="g-card">
        <header>{{ group.header | i18n }}</header>
        @for (item of group.items; track $index) {
          @if (item.value.startsWith('http')) {
            <a tuiCell [additionalItem]="item"></a>
          } @else {
            <button
              tuiCell
              [style.pointer-events]="!item.icon ? 'none' : null"
              [additionalItem]="item"
              (click)="item.action?.()"
            ></button>
          }
        }
      </section>
    }
  `,
  styles: `
    section {
      max-width: 42rem;
      display: flex;
      flex-direction: column;
      margin-bottom: 2rem;
    }
  `,
  host: { class: 'g-subpage' },
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [ServiceAdditionalItemComponent, TuiCell, i18nPipe],
})
export default class ServiceAboutRoute {
  private readonly pkgId = getPkgId()
  private readonly api = inject(ApiService)
  private readonly copyService = inject(CopyService)
  private readonly markdown = inject(DialogService).openComponent(MARKDOWN, {
    label: 'License',
    size: 'l',
    data: defer(() =>
      this.api.getStatic([`/s9pk/installed/${this.pkgId}.s9pk/LICENSE.md`], {}),
    ),
  })

  readonly groups = toSignal<{ header: i18nKey; items: AdditionalItem[] }[]>(
    inject<PatchDB<DataModel>>(PatchDB)
      .watch$('packageData', this.pkgId)
      .pipe(
        map(pkg => {
          const manifest = getManifest(pkg)

          return [
            {
              header: 'General',
              items: [
                {
                  name: 'Title',
                  value: manifest.title,
                },
                {
                  name: 'ID' as i18nKey,
                  value: manifest.id,
                },
                {
                  name: 'Version',
                  value: manifest.version,
                  icon: '@tui.copy',
                  action: () => this.copyService.copy(manifest.version),
                },
                {
                  name: 'Git hash',
                  value: manifest.gitHash || '-',
                  icon: manifest.gitHash ? '@tui.copy' : '',
                  action: () =>
                    manifest.gitHash && this.copyService.copy(manifest.gitHash),
                },
                {
                  name: 'SDK version',
                  value: manifest.sdkVersion || '-',
                  icon: manifest.sdkVersion ? '@tui.copy' : '',
                  action: () =>
                    manifest.sdkVersion &&
                    this.copyService.copy(manifest.sdkVersion),
                },
                {
                  name: 'License',
                  value: manifest.license,
                  icon: '@tui.chevron-right',
                  action: () => this.markdown.subscribe(),
                },
                {
                  name: 'Installed from',
                  value: pkg.registry || NOT_PROVIDED,
                },
              ],
            },
            {
              header: 'Links',
              items: [
                ...manifest.docsUrls.map(docsUrl => ({
                  name: 'Documentation',
                  value: docsUrl,
                })),
                {
                  name: 'Marketing',
                  value: manifest.marketingUrl || NOT_PROVIDED,
                },
                {
                  name: 'Donations',
                  value: manifest.donationUrl || NOT_PROVIDED,
                },
              ],
            },
            {
              header: 'Source Code',
              items: [
                {
                  name: 'Upstream service',
                  value: manifest.upstreamRepo,
                },
                {
                  name: 'StartOS package',
                  value: manifest.packageRepo,
                },
              ],
            },
          ]
        }),
      ),
  )
}
