name: Build WebView wrappers

on:
  workflow_dispatch:
    inputs:
      tag:
        required: true
        description: "Ref to build from (e.g. v1.0.0)"
  push:
    tags:
      - "v*"

jobs:
  build:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        include:
          - os: ubuntu-latest
            arch: amd64
          - os: ubuntu-latest
            arch: arm64
          - os: macos-latest
            arch: arm64
          - os: windows-latest
            arch: amd64
          - os: windows-latest
            arch: arm64

    permissions:
      packages: write
      contents: write

    env:
      PYTHON_VERSION: 3.11
      PNPM_VERSION: 10
      NODE_VERSION: 20
      TAG_NAME: ${{ github.event.inputs.tag || github.ref_name }}

    steps:
      - name: Checkout source repo
        uses: actions/checkout@v4
        with:
          ref: ${{ env.TAG_NAME }}

      - name: Cache Chocolatey packages
        if: matrix.os == 'windows-latest'
        uses: actions/cache@v4
        with:
          path: C:\ProgramData\chocolatey\lib
          key: choco-${{ runner.os }}-${{ matrix.arch }}-qt6
          restore-keys: |
            choco-${{ runner.os }}-${{ matrix.arch }}-

      - name: Install Qt (Windows)
        if: matrix.os == 'windows-latest'
        run: choco install -y qt6-base-dev

      - name: Cache Python venv
        id: cache-python
        uses: actions/cache@v4
        with:
          path: .venv
          key: uv-${{ runner.os }}-${{ matrix.arch }}-${{ env.PYTHON_VERSION }}-${{ hashFiles('uv.lock') }}
          restore-keys: |
            uv-${{ runner.os }}-${{ matrix.arch }}-${{ env.PYTHON_VERSION }}-

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: ${{ env.PYTHON_VERSION }}
          architecture: "x64"

      - name: Install Python dependencies
        run: |
          pip install uv
          uv venv --system-site-packages --relocatable
          uv sync --link-mode=copy --active

      - name: Install PyInstaller + Qt backend (Windows)
        if: matrix.os == 'windows-latest'
        run: |
          uv pip install pyinstaller pywebview QtPy PySide6

      - name: Install PyInstaller + Qt backend (Other OSs)
        if: matrix.os != 'windows-latest'
        run: |
          uv pip install pyinstaller pywebview[qt]

      - name: Install pnpm
        uses: pnpm/action-setup@v4
        with:
          version: ${{ env.PNPM_VERSION }}

      - name: Install Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: pnpm
          cache-dependency-path: "ui/pnpm-lock.yaml"

      - name: Build frontend
        working-directory: ui
        run: |
          pnpm install --production --prefer-offline --frozen-lockfile
          pnpm run generate

      - name: Build native binary
        run: |
          uv run pyinstaller ./app.spec

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: app-${{ runner.os }}-${{ matrix.arch }}-${{ env.TAG_NAME }}
          path: dist/*

      - name: Package artifact (Unix)
        if: startsWith(env.TAG_NAME, 'v') && runner.os != 'Windows'
        run: |
          mkdir -p release
          ZIP_NAME="ytptube-${{ runner.os }}-${{ matrix.arch }}-${{ env.TAG_NAME }}.zip"

          if [ ! -d dist ] || [ -z "$(ls -A dist)" ]; then
            echo "dist directory is empty, skipping packaging."
            exit 1
          fi

          zip -r "release/${ZIP_NAME}" dist/

      - name: Package artifact (Windows)
        if: startsWith(env.TAG_NAME, 'v') && runner.os == 'Windows'
        shell: powershell
        run: |
          $zipName = "ytptube-${{ runner.os }}-${{ matrix.arch }}-${{ env.TAG_NAME }}.zip"
          New-Item -ItemType Directory -Force -Path release | Out-Null

          if (!(Test-Path dist) -or !(Get-ChildItem -Path dist)) {
            Write-Host "dist directory is empty, skipping packaging."
            exit 1
          }

          Compress-Archive -Path dist\* -DestinationPath "release\$zipName"

      - name: Upload to GitHub Release
        if: startsWith(env.TAG_NAME, 'v')
        uses: softprops/action-gh-release@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ env.TAG_NAME }}
          files: release/*.zip
