# «Контракт-чек» — everyday commands (uv + docker)
# Usage: make <target>   (see `make help`)

.PHONY: help install lint lint-fix isort isort-check typecheck test test-unit test-integration migrate \
        infra-up infra-down infra-logs services-up services-down services-logs \
        api api-logs bot bot-logs worker-extract worker-analyze worker-notify \
        seed-token jwt-secret jwt-token jwt-verify health shell-api shell-bot \
        shell-db admin-promote admin-list clean

# ─────────────────────────────────────────────────────────────────────────────
# Help
# ─────────────────────────────────────────────────────────────────────────────
help:  ## Show available commands
	@echo "Usage: make <target>"
	@grep -E '^[a-zA-Z0-9_-]+:.*##' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*##"}; {printf "  \033[36m%-18s\033[0m %s\n", $$1, $$2}'

# ─────────────────────────────────────────────────────────────────────────────
# Local dev (uv)
# ─────────────────────────────────────────────────────────────────────────────
install:  ## Sync dev dependencies (uv)
	uv sync --group dev

lint:  ## Run ruff linter + format check
	uv run ruff check src tests
	uv run ruff format --check src tests

lint-fix:  ## Run ruff autofix + format + isort fix
	uv run ruff check --fix src tests
	uv run ruff format src tests
	uv run isort src tests

isort:  ## Run isort (sort imports in-place)
	uv run isort src tests

isort-check:  ## Run isort in check-only mode
	uv run isort --check-only src tests

typecheck:  ## Run ty type checker
	uv run ty check src

test:  ## Run all tests (unit + integration)
	uv run pytest

test-unit:  ## Run unit tests only (fast)
	uv run pytest -m "not integration"

test-cov:  ## Run unit tests with coverage report (enforces threshold)
	uv run pytest --cov=src/contract_check --cov-branch --cov-report=term-missing --cov-report=html --cov-fail-under=59 -m "not integration" tests/unit

test-integration:  ## Run integration tests (needs docker infra)
	uv run pytest -m integration

# ─────────────────────────────────────────────────────────────────────────────
# Docker: infrastructure (postgres + redis + rabbitmq + minio)
# ─────────────────────────────────────────────────────────────────────────────
infra-up:  ## Start infra containers
	docker compose up -d

infra-down:  ## Stop infra containers
	docker compose down

infra-logs:  ## Tail infra logs
	docker compose logs -f

# ─────────────────────────────────────────────────────────────────────────────
# Docker: all services (api + workers + bot)
# ─────────────────────────────────────────────────────────────────────────────
services-up:  ## Start all services (needs infra running)
	docker compose --profile services up -d --build --remove-orphans

services-down:  ## Stop all services
	docker compose --profile services down

services-logs:  ## Tail all service logs
	docker compose --profile services logs -f

services-ps:  ## Show running containers
	docker compose --profile services ps

services-nginx:  ## Start with nginx reverse proxy
	docker compose --profile services --profile edge up -d --build --remove-orphans

# ─────────────────────────────────────────────────────────────────────────────
# Docker: nginx edge (reverse proxy)
# ─────────────────────────────────────────────────────────────────────────────
nginx-up:  ## Start nginx
	docker compose --profile edge up -d --build --remove-orphans

nginx-down:  ## Stop nginx
	docker compose --profile edge down

nginx-logs:  ## Tail nginx logs
	docker compose --profile edge logs -f

nginx-ps:  ## Show running containers
	docker compose --profile edge ps

# ─────────────────────────────────────────────────────────────────────────────
# Individual services
# ─────────────────────────────────────────────────────────────────────────────
api:  ## Start/restart API service
	docker compose --profile services up -d --build --remove-orphans api

api-logs:  ## Tail API logs
	docker compose logs -f api

bot:  ## Start/restart Telegram bot
	docker compose --profile services up -d --build --remove-orphans bot

bot-logs:  ## Tail bot logs
	docker compose logs -f bot

worker-extract:  ## Start/restart extract worker
	docker compose --profile services up -d --build --remove-orphans worker-extract

worker-analyze:  ## Start/restart analyze worker
	docker compose --profile services up -d --build --remove-orphans worker-analyze

worker-analyze-logs:  ## Tail analyze worker logs
	docker compose logs -f worker-analyze

worker-prescreen:  ## Start/restart prescreen worker
	docker compose --profile services up -d --build --remove-orphans worker-prescreen

worker-prescreen-logs:  ## Tail prescreen worker logs
	docker compose logs -f worker-prescreen

worker-notify:  ## Start/restart notify worker
	docker compose --profile services up -d --build --remove-orphans worker-notify

worker-notify-logs:  ## Tail notify worker logs
	docker compose logs -f worker-notify

# ─────────────────────────────────────────────────────────────────────────────
# Database
# ─────────────────────────────────────────────────────────────────────────────
migrate:  ## Run Alembic migrations (inside api container)
	docker compose --profile services build api
	docker compose --profile services run --rm api alembic upgrade head

shell-db:  ## Open psql inside postgres container
	docker compose exec postgres psql -U contract_check -d contract_check

# ─────────────────────────────────────────────────────────────────────────────
# Admin panel (/admin — manage users; needs role = 'admin')
# ─────────────────────────────────────────────────────────────────────────────
admin-promote:  ## Grant admin role to a user (usage: make admin-promote EMAIL=a@b.c)
	@if [ -z "$(EMAIL)" ]; then \
		echo "Usage: make admin-promote EMAIL=a@b.c"; \
		exit 1; \
	fi
	@docker compose exec -T postgres psql -U contract_check -d contract_check \
		-c "UPDATE users SET role = 'admin' WHERE email = '$(EMAIL)';" \
		-c "SELECT id, email, role FROM users WHERE email = '$(EMAIL)';"

admin-list:  ## List current admin users
	@docker compose exec -T postgres psql -U contract_check -d contract_check \
		-c "SELECT id, email, telegram_id, role, is_active FROM users WHERE role = 'admin';"

# ─────────────────────────────────────────────────────────────────────────────
# Auth / tokens
# ─────────────────────────────────────────────────────────────────────────────
seed-token:  ## Generate bot service token (prints bearer token)
	docker compose --profile services exec api python -m contract_check.api seed-token bot-prod bot

jwt-secret:  ## Generate a fresh JWT_SECRET for .env
	@openssl rand -hex 32

jwt-token:  ## Exchange a telegram_id for a user JWT (usage: make jwt-token TG_ID=123456)
	@if [ -z "$(TG_ID)" ]; then \
		echo "Usage: make jwt-token TG_ID=123456"; \
		exit 1; \
	fi
	@TOKEN=$$(grep -E '^BOT_SERVICE_TOKEN=' .env | cut -d= -f2); \
	if [ -z "$$TOKEN" ]; then \
		echo "BOT_SERVICE_TOKEN not found in .env"; \
		exit 1; \
	fi; \
	curl -s -X POST -H "Authorization: Bearer $$TOKEN" \
		-H "Content-Type: application/json" \
		-d '{"telegram_id":$(TG_ID)}' \
		http://localhost:8000/api/v1/auth/telegram/bot | jq .

jwt-verify:  ## Introspect a user JWT (usage: make jwt-verify JWT=eyJ...)
	@if [ -z "$(JWT)" ]; then \
		echo "Usage: make jwt-verify JWT=eyJ..."; \
		exit 1; \
	fi
	@curl -s -H "Authorization: Bearer $(JWT)" \
		http://localhost:8000/api/v1/auth/me | jq .

# ─────────────────────────────────────────────────────────────────────────────
# Health / diagnostics
# ─────────────────────────────────────────────────────────────────────────────
health:  ## Check API health endpoint
	@echo "API health:"
	@curl -s http://localhost:8000/healthz | jq . 2>/dev/null || curl -s http://localhost:8000/healthz
	@echo ""
	@echo "RabbitMQ:   http://localhost:15672  (guest/guest → contract_check/contract_check)"
	@echo "MinIO:      http://localhost:9001   (contract_check/contract_check)"
	@echo "Postgres:   localhost:15432         (contract_check/contract_check)"

shell-api:  ## Open shell inside API container
	docker compose --profile services exec api /bin/sh

shell-bot:  ## Open shell inside bot container
	docker compose --profile services exec bot /bin/sh

# ─────────────────────────────────────────────────────────────────────────────
# Cleanup
# ─────────────────────────────────────────────────────────────────────────────
clean:  ## Remove containers, volumes, caches
	docker compose --profile services down -v
	docker compose down -v
	rm -rf .pytest_cache .ruff_cache
	uv cache clean

# ─────────────────────────────────────────────────────────────────────────────
# Full workflow shortcuts
# ─────────────────────────────────────────────────────────────────────────────
dev: install infra-up migrate services-up  ## Bootstrap full dev environment

stop: services-down infra-down  ## Stop everything
