.PHONY: all dev build test lint clean \
	backend-build backend-run backend-dev backend-test backend-test-all backend-test-unit backend-test-integration backend-test-coverage \
	backend-lint backend-clean backend-deps backend-generate \
	backend-db-up backend-db-down backend-db-status backend-db-create \
	test-mysql-up test-mysql-down test-mysql test-mysql-quick \
	frontend-build frontend-dev frontend-test frontend-test-watch frontend-test-coverage frontend-test-e2e frontend-lint frontend-clean \
	desktop-build desktop-build-mac desktop-build-win desktop-build-linux \
	desktop-dev desktop-test desktop-clean \
	desktop-prepare-frontend desktop-prepare-embedfs desktop-prepare-windows-resource

# ============================================
# 顶层便捷命令
# ============================================

dev:
	@echo "🚀 Starting development environment..."
	@$(MAKE) -j2 backend-dev frontend-dev

build: backend-build frontend-build
	@echo "✅ Build complete"

test: backend-test desktop-test frontend-test
	@echo "✅ All tests passed"

lint: backend-lint frontend-lint
	@echo "✅ Lint complete"

all: build test lint

# ============================================
# 后端
# ============================================

backend-build:
	cd backend && go build -o bin/server ./cmd/server

backend-run:
	cd backend && go run ./cmd/server

backend-dev:
	cd backend && go run ./cmd/server

backend-test:
	cd backend && go test ./internal/... ./pkg/... ./tests/... ./cmd/server/... -v

backend-test-all:
	cd backend && go test ./... -v

backend-test-unit:
	cd backend && go test ./internal/... ./pkg/... -v

backend-test-integration:
	cd backend && go test ./tests/... -v

backend-test-coverage:
	cd backend && go test ./... -coverprofile=coverage.out
	cd backend && go tool cover -html=coverage.out -o coverage.html
	@echo "Coverage report generated: backend/coverage.html"

backend-lint:
	cd backend && go tool golangci-lint run ./...

backend-clean:
	rm -rf backend/bin/ backend/coverage.out backend/coverage.html

backend-deps:
	cd backend && go mod tidy

backend-generate:
	cd backend && go generate ./...

backend-db-up:
	@echo "Running database migration up..."
	cd backend && goose -dir migrations/sqlite sqlite3 "$(DB_PATH)" up

backend-db-down:
	@echo "Running database migration down..."
	cd backend && goose -dir migrations/sqlite sqlite3 "$(DB_PATH)" down

backend-db-status:
	@echo "Checking database migration status..."
	cd backend && goose -dir migrations/sqlite sqlite3 "$(DB_PATH)" status

backend-db-create:
	@read -p "Migration name: " name; \
	cd backend && goose -dir migrations/sqlite create $$name sql; \
	cd backend && goose -dir migrations/mysql create $$name sql

# ============================================
# MySQL 专项测试
# ============================================

test-mysql-up:
	@echo "Starting MySQL test container..."
	cd backend/tests/mysql && docker-compose up -d
	@echo "Waiting for MySQL to be ready..."
	@for i in $$(seq 1 30); do \
		if docker exec nex-mysql-test mysqladmin ping -h localhost -u root -ptestpass --silent 2>/dev/null; then \
			echo "MySQL is ready!"; \
			exit 0; \
		fi; \
		echo "Waiting... ($$i/30)"; \
		sleep 1; \
	done; \
	echo "MySQL failed to start"; \
	exit 1

test-mysql-down:
	@echo "Stopping MySQL test container..."
	cd backend/tests/mysql && docker-compose down -v

test-mysql: test-mysql-up
	@echo "Running MySQL tests..."
	cd backend && go test -tags=mysql ./tests/mysql/... -v -count=1
	$(MAKE) test-mysql-down

test-mysql-quick:
	@echo "Running MySQL tests (without container management)..."
	cd backend && go test -tags=mysql ./tests/mysql/... -v -count=1

# ============================================
# 前端
# ============================================

frontend-install:
	cd frontend && bun install

frontend-build: frontend-install
	cd frontend && bun run build

frontend-dev: frontend-install
	cd frontend && bun dev

frontend-test: frontend-install
	cd frontend && bun run test

frontend-test-watch: frontend-install
	cd frontend && bun run test:watch

frontend-test-coverage: frontend-install
	cd frontend && bun run test:coverage

frontend-test-e2e: frontend-install
	cd frontend && bun run test:e2e

frontend-lint: frontend-install
	cd frontend && bun run lint

frontend-clean:
	rm -rf frontend/dist frontend/.next frontend/node_modules frontend/coverage frontend/playwright-report frontend/test-results frontend/tsconfig.tsbuildinfo

# ============================================
# 桌面应用
# ============================================

desktop-build: desktop-build-mac desktop-build-win desktop-build-linux
	@echo "✅ Desktop builds complete for all platforms"

desktop-prepare-frontend:
	@echo "📦 Preparing frontend for desktop..."
ifeq ($(OS),Windows_NT)
	powershell -NoProfile -Command "Copy-Item -LiteralPath 'frontend/.env.desktop' -Destination 'frontend/.env.production.local' -Force"
	cd frontend && bun install && bun run build
	powershell -NoProfile -Command "Remove-Item -LiteralPath 'frontend/.env.production.local' -Force -ErrorAction SilentlyContinue"
else
	cd frontend && cp .env.desktop .env.production.local
	cd frontend && bun install && bun run build
	rm -f frontend/.env.production.local
endif

desktop-prepare-embedfs:
	@echo "📦 Preparing embedded filesystem..."
ifeq ($(OS),Windows_NT)
	powershell -NoProfile -Command "Remove-Item -LiteralPath 'embedfs/assets' -Recurse -Force -ErrorAction SilentlyContinue; Remove-Item -LiteralPath 'embedfs/frontend-dist' -Recurse -Force -ErrorAction SilentlyContinue; Copy-Item -LiteralPath 'assets' -Destination 'embedfs/assets' -Recurse; Copy-Item -LiteralPath 'frontend/dist' -Destination 'embedfs/frontend-dist' -Recurse"
else
	rm -rf embedfs/assets embedfs/frontend-dist
	cp -r assets embedfs/assets
	cp -r frontend/dist embedfs/frontend-dist
endif

desktop-prepare-windows-resource:
	@echo "📦 Preparing Windows executable icon..."
ifeq ($(OS),Windows_NT)
	cd backend/cmd/desktop && windres -O coff -F pe-x86-64 -i icon_windows.rc -o rsrc_windows_amd64.syso
else
	@if command -v x86_64-w64-mingw32-windres >/dev/null 2>&1; then \
		cd backend/cmd/desktop && x86_64-w64-mingw32-windres -O coff -F pe-x86-64 -i icon_windows.rc -o rsrc_windows_amd64.syso; \
	elif command -v windres >/dev/null 2>&1; then \
		cd backend/cmd/desktop && windres -O coff -F pe-x86-64 -i icon_windows.rc -o rsrc_windows_amd64.syso; \
	else \
		echo "❌ 未找到 windres，无法生成 Windows exe 图标资源"; \
		exit 1; \
	fi
endif

desktop-build-mac: desktop-prepare-frontend desktop-prepare-embedfs
	@echo "🍎 Building macOS..."
	cd backend && CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 go build -o ../build/nex-mac-arm64 ./cmd/desktop
	cd backend && CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 go build -o ../build/nex-mac-amd64 ./cmd/desktop
	lipo -create build/nex-mac-arm64 build/nex-mac-amd64 -output build/nex-mac-universal
	@echo "📦 Packaging macOS .app..."
	mkdir -p build/Nex.app/Contents/MacOS build/Nex.app/Contents/Resources
	cp build/nex-mac-universal build/Nex.app/Contents/MacOS/nex
	@if [ -f assets/icon.icns ]; then \
		cp assets/icon.icns build/Nex.app/Contents/Resources/; \
	else \
		echo "⚠️  未找到 assets/icon.icns"; \
	fi
	@MIN_MACOS_VERSION=$$(vtool -show-build build/nex-mac-universal | awk '/minos / {print $$2; exit}'); \
	if [ -z "$$MIN_MACOS_VERSION" ]; then \
		echo "❌ 无法读取 macOS 最低系统版本"; \
		exit 1; \
	fi; \
	{ \
		printf '%s\n' '<?xml version="1.0" encoding="UTF-8"?>' \
			'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' \
			'<plist version="1.0">' \
			'<dict>' \
			'    <key>CFBundleDevelopmentRegion</key>' \
			'    <string>zh-Hans</string>' \
			'    <key>CFBundleExecutable</key>' \
			'    <string>nex</string>' \
			'    <key>CFBundleIconFile</key>' \
			'    <string>icon</string>' \
			'    <key>CFBundleIdentifier</key>' \
			'    <string>com.lanyuanxiaoyao.nex</string>' \
			'    <key>CFBundleInfoDictionaryVersion</key>' \
			'    <string>6.0</string>' \
			'    <key>LSApplicationCategoryType</key>' \
			'    <string>public.app-category.developer-tools</string>' \
			'    <key>CFBundleName</key>' \
			'    <string>Nex</string>' \
			'    <key>CFBundleDisplayName</key>' \
			'    <string>Nex</string>' \
			'    <key>CFBundlePackageType</key>' \
			'    <string>APPL</string>' \
			'    <key>CFBundleShortVersionString</key>' \
			'    <string>1.0.0</string>' \
			'    <key>CFBundleVersion</key>' \
			'    <string>1.0.0</string>' \
			'    <key>NSHumanReadableCopyright</key>' \
			'    <string>Copyright © 2026 Nex</string>' \
			'    <key>LSMinimumSystemVersion</key>' \
			"    <string>$$MIN_MACOS_VERSION</string>" \
			'    <key>LSUIElement</key>' \
			'    <true/>' \
			'    <key>NSHighResolutionCapable</key>' \
			'    <true/>' \
			'</dict>' \
			'</plist>'; \
	} > build/Nex.app/Contents/Info.plist
	chmod +x build/Nex.app/Contents/MacOS/nex
	@echo "✅ macOS app packaged: build/Nex.app"

desktop-build-win: desktop-prepare-frontend desktop-prepare-embedfs desktop-prepare-windows-resource
	@echo "🪟 Building Windows..."
ifeq ($(OS),Windows_NT)
	powershell -NoProfile -Command "New-Item -ItemType Directory -Path 'build' -Force | Out-Null"
	cd backend && set "CGO_ENABLED=1"&& set "GOOS=windows"&& set "GOARCH=amd64"&& go build -ldflags "-H=windowsgui" -o ../build/nex-win-amd64.exe ./cmd/desktop
else
	mkdir -p build
	cd backend && CGO_ENABLED=1 GOOS=windows GOARCH=amd64 go build -ldflags "-H=windowsgui" -o ../build/nex-win-amd64.exe ./cmd/desktop
endif

desktop-build-linux: desktop-prepare-frontend desktop-prepare-embedfs
	@echo "🐧 Building Linux..."
	cd backend && CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -o ../build/nex-linux-amd64 ./cmd/desktop

desktop-dev: desktop-prepare-frontend desktop-prepare-embedfs
	@echo "🖥️  Starting desktop app in dev mode..."
	cd backend && go run ./cmd/desktop

desktop-test:
	cd backend && go test ./cmd/desktop/... -v

desktop-clean:
	rm -rf build/ embedfs/assets embedfs/frontend-dist

# ============================================
# 清理
# ============================================

clean: backend-clean frontend-clean desktop-clean
	@echo "✅ Clean complete"
