{
  description = "Koel - A personal music streaming server that works";
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    flake-utils.url = "github:numtide/flake-utils";
  };
  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        pkgs = import nixpkgs { inherit system; };
        # PHP with required extensions
        php = pkgs.php83.buildEnv {
          extensions = ({ enabled, all }: enabled ++ (with all; [
            exif
            gd
            fileinfo
            simplexml
            pdo
            pdo_mysql
            pdo_pgsql
            redis
            zip
            mbstring
            curl
            openssl
            tokenizer
            xml
            ctype
            bcmath
          ]));
          extraConfig = ''
            memory_limit = 512M
            upload_max_filesize = 100M
            post_max_size = 100M
          '';
        };
        # Composer with PHP
        composer = pkgs.phpPackages.composer.override {
          php = php;
        };
        # Node.js and pnpm
        nodejs = pkgs.nodejs_22;
        pnpm = pkgs.pnpm;
        # Development shell dependencies
        devDependencies = with pkgs; [
          php
          composer
          nodejs
          pnpm
          # Redis for cache/queue
          redis
          # FFmpeg for audio processing
          ffmpeg
          # Git for version control
          git
          # Utilities
          which
          curl
          wget
          gnused
          findutils
          procps
          sqlite
        ];
        # Helper scripts
        startScript = pkgs.writeShellScriptBin "koel-start" ''
          set -e
          echo "🎵 Starting Koel Development Environment"
          echo "========================================"
          # Check if .env exists
          if [ ! -f .env ]; then
            echo "📝 Creating .env file from .env.example..."
            cp .env.example .env
            echo "⚠️  Please edit .env and set your configuration"
            echo "   Required: APP_KEY, DB_*, MEDIA_PATH"
            exit 1
          fi
          # Check if vendor directory exists
          if [ ! -d vendor ]; then
            echo "📦 Installing PHP dependencies..."
            composer install
          fi
          # Check if node_modules exists
          if [ ! -d node_modules ]; then
            echo "📦 Installing Node dependencies..."
            pnpm install
          fi
          # Check if APP_KEY is set
          if ! grep -q "APP_KEY=base64:" .env 2>/dev/null; then
            echo "🔑 Generating application key..."
            php artisan key:generate
          fi
          # Build frontend assets if needed
          if [ ! -d public/build ]; then
            echo "🏗️  Building frontend assets..."
            pnpm run build
          fi
          echo ""
          echo "✅ Environment ready!"
          echo ""
          echo "Starting services..."
          echo "- Web server: http://localhost:8000"
          echo "- Queue worker"
          echo "- Vite dev server"
          echo ""
          echo "Press Ctrl+C to stop all services"
          echo ""
          # Start all services
          composer run dev
        '';
        setupScript = pkgs.writeShellScriptBin "koel-setup" ''
          set -e
          echo "🎵 Koel Initial Setup (SQLite)"
          echo "=============================="
          # Create .env if not exists
          if [ ! -f .env ]; then
            cp .env.example .env
            # Configure for SQLite
            sed -i 's/DB_CONNECTION=mysql/DB_CONNECTION=sqlite-persistent/' .env
            sed -i 's/^DB_HOST=/#DB_HOST=/' .env
            sed -i 's/^DB_PORT=/#DB_PORT=/' .env
            sed -i 's/^DB_DATABASE=/#DB_DATABASE=/' .env
            sed -i 's/^DB_USERNAME=/#DB_USERNAME=/' .env
            sed -i 's/^DB_PASSWORD=/#DB_PASSWORD=/' .env
            echo "✓ Created .env file (configured for SQLite)"
          fi
          # Create database directory and file
          mkdir -p database
          if [ ! -f database/database.sqlite ]; then
            touch database/database.sqlite
            echo "✓ Created SQLite database file"
          fi
          # Install dependencies
          echo ""
          echo "📦 Installing PHP dependencies..."
          composer install
          echo ""
          echo "📦 Installing Node dependencies..."
          pnpm install
          # Generate key
          echo ""
          echo "🔑 Generating application key..."
          php artisan key:generate
          # Build assets
          echo ""
          echo "🏗️  Building frontend assets..."
          pnpm run build
          echo ""
          echo "✅ Setup complete!"
          echo ""
          echo "Next steps:"
          echo "1. Edit .env and set MEDIA_PATH to your music directory"
          echo "2. Run: koel-init    (to initialize database)"
          echo "3. Run: koel-start   (to start the server)"
        '';
        initScript = pkgs.writeShellScriptBin "koel-init" ''
          set -e
          echo "🎵 Initializing Koel Database"
          echo "============================="
          php artisan koel:init
          echo ""
          echo "✅ Database initialized!"
          echo ""
          echo "Run 'koel-start' to start the server"
        '';
        stopScript = pkgs.writeShellScriptBin "koel-stop" ''
          echo "🛑 Stopping Koel services..."
          pkill -f "php artisan serve" || true
          pkill -f "php artisan queue" || true
          pkill -f "vite" || true
          echo "✅ All services stopped"
        '';
        # Build the application
        koelApp = pkgs.stdenv.mkDerivation {
          pname = "koel";
          version = builtins.readFile ./.version;
          src = ./.;
          nativeBuildInputs = [
            php
            composer
            nodejs
            pnpm
            pkgs.makeWrapper
          ];
          buildPhase = ''
            runHook preBuild
            # Set HOME for composer and npm
            export HOME=$TMPDIR
            export COMPOSER_CACHE_DIR=$TMPDIR/composer-cache
            export npm_config_cache=$TMPDIR/npm-cache
            # Install PHP dependencies
            echo "Installing PHP dependencies..."
            composer install --no-dev --no-interaction --no-progress --optimize-autoloader
            # Install Node dependencies
            echo "Installing Node dependencies..."
            pnpm install --frozen-lockfile
            # Build frontend assets
            echo "Building frontend assets..."
            pnpm run build
            runHook postBuild
          '';
          installPhase = ''
            runHook preInstall
            mkdir -p $out/share/koel
            # Copy application files
            cp -r . $out/share/koel/
            # Remove unnecessary files
            rm -rf $out/share/koel/node_modules
            rm -rf $out/share/koel/tests
            rm -rf $out/share/koel/.git
            rm -rf $out/share/koel/.github
            # Create bin directory and wrapper script
            mkdir -p $out/bin
            makeWrapper ${php}/bin/php $out/bin/koel-artisan \
              --add-flags "$out/share/koel/artisan" \
              --set APP_BASE_PATH "$out/share/koel"
            runHook postInstall
          '';
          meta = with pkgs.lib; {
            description = "A personal music streaming server that works";
            homepage = "https://koel.dev";
            license = licenses.mit;
            maintainers = [];
            platforms = platforms.linux ++ platforms.darwin;
          };
        };
      in
      {
        # Development shell
        devShells.default = pkgs.mkShell {
          buildInputs = devDependencies ++ [
            startScript
            setupScript
            initScript
            stopScript
          ];
          shellHook = ''
            echo "🎵 Koel Development Environment"
            echo "=============================="
            echo "PHP version: $(php --version | head -n 1)"
            echo "Node.js version: $(node --version)"
            echo "Composer version: $(composer --version)"
            echo "pnpm version: $(pnpm --version)"
            echo ""
            echo "🚀 Quick Start Commands:"
            echo "  koel-setup      - First time setup (install deps, build assets)"
            echo "  koel-init       - Initialize database"
            echo "  koel-start      - Start all services (web + queue + vite)"
            echo "  koel-stop       - Stop all services"
            echo ""
            echo "📚 Manual Commands:"
            echo "  composer install        - Install PHP dependencies"
            echo "  pnpm install           - Install Node dependencies"
            echo "  pnpm run build         - Build frontend assets"
            echo "  php artisan koel:init  - Initialize Koel"
            echo "  php artisan test       - Run tests"
            echo "  sqlite3 database/database.sqlite - Access SQLite database"
            echo ""
            echo "💾 Optional Services:"
            echo "  redis-server          - Redis cache (optional, for better performance)"
            echo ""
            # Set up environment
            export PATH="$PWD/vendor/bin:$PATH"
            # Check if this is first run
            if [ ! -f .env ] && [ ! -d vendor ]; then
              echo "👉 First time here? Run: koel-setup"
              echo ""
            fi
          '';
        };
        # Production package
        packages = {
          default = koelApp;
          koel = koelApp;
        };
        # NixOS module for Koel
        nixosModules.default = { config, lib, pkgs, ... }:
          with lib;
          let
            cfg = config.services.koel;
          in
          {
            options.services.koel = {
              enable = mkEnableOption "Koel music streaming server";
              package = mkOption {
                type = types.package;
                default = koelApp;
                description = "The Koel package to use";
              };
              dataDir = mkOption {
                type = types.path;
                default = "/var/lib/koel";
                description = "Directory where Koel stores its data";
              };
              host = mkOption {
                type = types.str;
                default = "127.0.0.1";
                description = "Host to bind to";
              };
              port = mkOption {
                type = types.port;
                default = 8000;
                description = "Port to listen on";
              };
              user = mkOption {
                type = types.str;
                default = "koel";
                description = "User account under which Koel runs";
              };
              group = mkOption {
                type = types.str;
                default = "koel";
                description = "Group under which Koel runs";
              };
              envFile = mkOption {
                type = types.nullOr types.path;
                default = null;
                description = "Path to the .env file";
              };
            };
            config = mkIf cfg.enable {
              users.users.${cfg.user} = {
                isSystemUser = true;
                group = cfg.group;
                home = cfg.dataDir;
                createHome = true;
              };
              users.groups.${cfg.group} = {};
              systemd.services.koel = {
                description = "Koel Music Streaming Server";
                after = [ "network.target" "mysql.service" "redis.service" ];
                wantedBy = [ "multi-user.target" ];
                serviceConfig = {
                  Type = "simple";
                  User = cfg.user;
                  Group = cfg.group;
                  WorkingDirectory = "${cfg.package}/share/koel";
                  EnvironmentFile = mkIf (cfg.envFile != null) cfg.envFile;
                  ExecStart = "${php}/bin/php ${cfg.package}/share/koel/artisan serve --host=${cfg.host} --port=${toString cfg.port}";
                  Restart = "on-failure";
                  RestartSec = 5;
                  # Security hardening
                  NoNewPrivileges = true;
                  PrivateTmp = true;
                  ProtectSystem = "strict";
                  ProtectHome = true;
                  ReadWritePaths = [ cfg.dataDir ];
                };
              };
              systemd.services.koel-queue = {
                description = "Koel Queue Worker";
                after = [ "network.target" "mysql.service" "redis.service" ];
                wantedBy = [ "multi-user.target" ];
                serviceConfig = {
                  Type = "simple";
                  User = cfg.user;
                  Group = cfg.group;
                  WorkingDirectory = "${cfg.package}/share/koel";
                  EnvironmentFile = mkIf (cfg.envFile != null) cfg.envFile;
                  ExecStart = "${php}/bin/php ${cfg.package}/share/koel/artisan queue:work --tries=3";
                  Restart = "on-failure";
                  RestartSec = 5;
                };
              };
            };
          };
      }
    );
}