#!/bin/bash
# Impozytor – program uruchamiający (macOS).
#  * dwuklik na Impozytor.app  → serwer w tle, przeglądarka, okno „Zatrzymaj”
#  * "Uruchom Impozytor.command" wywołuje ten sam skrypt z --terminal (log w oknie Terminala)
# Kod programu: w pakiecie (Contents/Resources/impozytor – wersja samodzielna) albo w folderze obok Impozytor.app.
# Dane (baza, wgrane pliki, wyniki, kopie): ~/Library/Application Support/Impozytor/data
# Log: ~/Library/Logs/Impozytor.log

MODE="app"; [ "$1" = "--terminal" ] && MODE="terminal"
HERE="$(cd "$(dirname "$0")" && pwd)"
RES="$HERE/../Resources"
if [ -f "$RES/impozytor/app/main.py" ]; then
  ROOT="$(cd "$RES/impozytor" && pwd)"
else
  ROOT="$(cd "$HERE/../../.." && pwd)"
fi
[ -f "$ROOT/app/main.py" ] || { echo "Nie znaleziono kodu programu (app/main.py) ani w pakiecie, ani obok Impozytor.app."; exit 1; }

export PATH="/opt/homebrew/bin:/usr/local/bin:/Library/Frameworks/Python.framework/Versions/Current/bin:$PATH"
PORT="${IMPOZYTOR_PORT:-8765}"
HOST="${IMPOZYTOR_HOST:-127.0.0.1}"      # 0.0.0.0 = udostępnij w sieci drukarni
SUPPORT="$HOME/Library/Application Support/Impozytor"
LOGDIR="$HOME/Library/Logs"; LOG="$LOGDIR/Impozytor.log"
mkdir -p "$SUPPORT" "$LOGDIR" 2>/dev/null || { SUPPORT="$ROOT"; LOG="$ROOT/impozytor.log"; }
export IMPOZYTOR_DATA="${IMPOZYTOR_DATA:-$SUPPORT/data}"

say()    { echo "▶ $1"; [ "$MODE" = "app" ] && osascript -e "display notification \"$1\" with title \"Impozytor\"" >/dev/null 2>&1; }
fail()   {
  echo "✖ $1"
  # macOS blokuje dostęp aplikacji do folderów Pobrane/Dokumenty/Biurko (ochrona prywatności) – typowy objaw: "Operation not permitted"
  if grep -q "Operation not permitted" "$LOG" 2>/dev/null && echo "$ROOT" | grep -Eq "/(Downloads|Documents|Desktop)(/|$)"; then
    set -- "$1

Przyczyna: macOS nie pozwala aplikacji czytać plików w folderze Pobrane / Dokumenty / Biurko (ochrona prywatności).
Rozwiązanie: przenieś folder „impozytor” np. do folderu domowego (wojtek) albo do Programy i uruchom stamtąd,
albo w Ustawieniach systemowych → Prywatność i ochrona → Pliki i foldery pozwól Impozytorowi na dostęp do tego folderu."
  fi
  # ostatnie linie logu w komunikacie – żeby od razu było widać przyczynę (bez szukania pliku)
  TAIL=$(tail -n 12 "$LOG" 2>/dev/null | cut -c1-160 | sed 's/"/\x27/g' | tr -d '\\' )
  if [ "$MODE" = "app" ]; then
    BTN=$(osascript -e "display dialog \"$1\n\nOstatnie linie logu:\n$TAIL\" buttons {\"Pokaż log\", \"OK\"} default button 2 with icon stop with title \"Impozytor\"" 2>/dev/null)
    case "$BTN" in *"Pokaż"*) open "$LOG" ;; esac
  else
    echo "--- ostatnie linie logu ($LOG):"; echo "$TAIL"; read -r -p "Naciśnij Enter, aby zamknąć…"
  fi
  exit 1
}
alive()  { curl -s -m 2 "http://127.0.0.1:$PORT/api/health" >/dev/null 2>&1; }

# Już działa (np. drugi dwuklik)? Ta sama wersja -> tylko otwórz przeglądarkę; starsza wersja -> zaproponuj restart.
LOCAL_VER=$(sed -n 's/^VERSION = "\(.*\)"/\1/p' "$ROOT/app/main.py" | head -1)
if alive; then
  RUN_VER=$(curl -s -m 2 "http://127.0.0.1:$PORT/api/health" | sed -n 's/.*"version":"\([^"]*\)".*/\1/p')
  if [ -n "$LOCAL_VER" ] && [ "$RUN_VER" != "$LOCAL_VER" ]; then
    if [ "$MODE" = "app" ]; then
      BTN=$(osascript -e "display dialog \"Działa już Impozytor w wersji $RUN_VER, a ta aplikacja to wersja $LOCAL_VER.\n\nZatrzymać starą wersję i uruchomić nową?\" buttons {\"Anuluj\", \"Uruchom nową\"} default button 2 with title \"Impozytor\"" 2>/dev/null)
      case "$BTN" in *"Uruchom"*) ;; *) exit 0 ;; esac
    else
      echo "▶ Działa już Impozytor $RUN_VER (ta wersja: $LOCAL_VER) – zatrzymuję starą i uruchamiam nową."
    fi
    OLD=$(lsof -ti tcp:"$PORT" -sTCP:LISTEN 2>/dev/null); [ -n "$OLD" ] && kill $OLD 2>/dev/null
    for i in $(seq 1 20); do alive || break; sleep 0.5; done   # poczekaj, aż stary serwer zwolni port
  else
    # ta sama wersja już działa: w trybie aplikacji otwórz kolejne natywne okno na działającym serwerze, inaczej przeglądarkę
    if [ "$MODE" = "app" ] && [ -x "$ROOT/.venv/bin/python" ] && "$ROOT/.venv/bin/python" -c "import webview" >/dev/null 2>&1; then
      exec "$ROOT/.venv/bin/python" "$ROOT/desktop.py" >>"$LOG" 2>&1
    fi
    if [ "$MODE" = "app" ] && [ -x "$SUPPORT/venv/bin/python" ] && "$SUPPORT/venv/bin/python" -c "import webview" >/dev/null 2>&1; then
      exec "$SUPPORT/venv/bin/python" "$ROOT/desktop.py" >>"$LOG" 2>&1
    fi
    say "Impozytor już działa – otwieram przeglądarkę."; open "http://127.0.0.1:$PORT"; exit 0
  fi
fi

# Migracja danych ze starszych wersji (data/ obok programu -> Application Support), jednorazowo.
if [ ! -d "$IMPOZYTOR_DATA" ] && [ -d "$ROOT/data" ] && [ "$ROOT/data" != "$IMPOZYTOR_DATA" ]; then
  say "Przenoszę dane (zlecenia, klienci, cennik) do: $IMPOZYTOR_DATA"
  cp -R "$ROOT/data" "$IMPOZYTOR_DATA" && mv "$ROOT/data" "$ROOT/data.przeniesione" 2>/dev/null
fi
mkdir -p "$IMPOZYTOR_DATA"
# Dostęp z telefonu / innych komputerów (Ustawienia → „Telefon i inne komputery”): flaga w folderze danych
if [ -z "$IMPOZYTOR_HOST" ] && [ -f "$IMPOZYTOR_DATA/lan_enabled" ]; then HOST="0.0.0.0"; fi
export IMPOZYTOR_HOST="$HOST" IMPOZYTOR_PORT="$PORT"

# Python
command -v python3 >/dev/null 2>&1 || fail "Nie znaleziono Pythona 3. Zainstaluj go z https://www.python.org/downloads/macos/ (3.10 lub nowszy) albo wpisz w Terminalu: xcode-select --install"
PYV=$(python3 -c 'import sys; print(sys.version_info[0]*100+sys.version_info[1])' 2>/dev/null || echo 0)
[ "$PYV" -ge 309 ] || fail "Python jest za stary ($(python3 --version 2>&1)). Potrzebny 3.9 lub nowszy."

# Środowisko z bibliotekami: .venv obok kodu (jeśli jest) albo w Application Support; reinstalacja, gdy zmieni się requirements.txt
if [ -x "$ROOT/.venv/bin/python" ]; then VENV="$ROOT/.venv"; else VENV="$SUPPORT/venv"; fi
REQ_MD5=$(cat "$ROOT/requirements.txt" "$ROOT/requirements-desktop.txt" 2>/dev/null | python3 -c 'import hashlib,sys; print(hashlib.md5(sys.stdin.buffer.read()).hexdigest())')
STAMP="$VENV/.requirements.md5"
# uszkodzone środowisko (np. po aktualizacji macOS/Pythona interpreter, do którego wskazuje venv, już nie istnieje) -> utwórz od nowa
if [ -e "$VENV/bin/python" ] && ! "$VENV/bin/python" -c "import sys" >/dev/null 2>&1; then
  echo "=== $(date) venv uszkodzony – tworzę od nowa: $VENV" >>"$LOG"; rm -rf "$VENV"
fi
if ! "$VENV/bin/python" -c "import uvicorn, fastapi, pikepdf, pypdfium2, reportlab, segno" >/dev/null 2>&1 || [ "$(cat "$STAMP" 2>/dev/null)" != "$REQ_MD5" ]; then
  say "Pierwsze uruchomienie: instaluję biblioteki (1–3 min, potrzebny internet)…"
  echo "=== $(date) instalacja bibliotek ($(python3 --version 2>&1), venv: $VENV)" >>"$LOG"
  { [ -x "$VENV/bin/python" ] || python3 -m venv "$VENV"; } >>"$LOG" 2>&1 || fail "Nie udało się utworzyć środowiska Python. Szczegóły: $LOG"
  "$VENV/bin/python" -m pip install --upgrade pip >>"$LOG" 2>&1
  if ! "$VENV/bin/python" -m pip install -r "$ROOT/requirements.txt" >>"$LOG" 2>&1; then
    # druga próba na świeżym środowisku (stare venv bywa niekompletne)
    echo "=== $(date) ponawiam na nowym venv" >>"$LOG"; rm -rf "$VENV"; python3 -m venv "$VENV" >>"$LOG" 2>&1
    "$VENV/bin/python" -m pip install --upgrade pip >>"$LOG" 2>&1
    "$VENV/bin/python" -m pip install -r "$ROOT/requirements.txt" >>"$LOG" 2>&1 || fail "Instalacja bibliotek nie powiodła się. Szczegóły: $LOG"
  fi
  # natywne okno (pywebview + pyobjc) – gdy się nie zainstaluje, program użyje przeglądarki
  "$VENV/bin/python" -m pip install pywebview >>"$LOG" 2>&1 || echo "pywebview: instalacja nieudana – będzie tryb przeglądarki" >>"$LOG"
  echo "$REQ_MD5" > "$STAMP"
fi

cd "$ROOT" || exit 1
if [ "$MODE" = "terminal" ]; then
  echo "▶ Impozytor startuje na http://$HOST:$PORT  (dane: $IMPOZYTOR_DATA; zamknij to okno, aby zatrzymać)"
  ( for i in $(seq 1 60); do alive && break; sleep 0.5; done; open "http://127.0.0.1:$PORT" ) &
  exec "$VENV/bin/python" -m uvicorn app.main:app --host "$HOST" --port "$PORT"
fi

# Tryb aplikacji: natywne okno (desktop.py: serwer w tle + okno WebKit; gdy brak pywebview – przeglądarka + okno „Zatrzymaj”)
echo "=== $(date) start (app) ===" >>"$LOG"
if [ -f "$ROOT/desktop.py" ] && "$VENV/bin/python" -c "import webview" >/dev/null 2>&1; then
  exec "$VENV/bin/python" "$ROOT/desktop.py" >>"$LOG" 2>&1
fi
"$VENV/bin/python" -m uvicorn app.main:app --host "$HOST" --port "$PORT" >>"$LOG" 2>&1 &
PID=$!
for i in $(seq 1 60); do alive && break; kill -0 $PID 2>/dev/null || fail "Serwer nie wystartował. Szczegóły: $LOG"; sleep 0.5; done
alive || { kill $PID 2>/dev/null; fail "Serwer nie odpowiada na porcie $PORT. Szczegóły: $LOG"; }
open "http://127.0.0.1:$PORT"
while kill -0 $PID 2>/dev/null; do
  BTN=$(osascript -e "display dialog \"Impozytor działa: http://127.0.0.1:$PORT\n\nOkno przeglądarki możesz zamykać i otwierać ponownie — program pracuje, dopóki nie klikniesz Zatrzymaj.\n\nDane: $IMPOZYTOR_DATA\" buttons {\"Otwórz w przeglądarce\", \"Zatrzymaj\"} default button 1 with title \"Impozytor\" with icon note" 2>/dev/null)
  case "$BTN" in
    *"Otwórz"*) open "http://127.0.0.1:$PORT" ;;
    *) break ;;
  esac
done
kill $PID 2>/dev/null; wait $PID 2>/dev/null
echo "=== $(date) stop ===" >>"$LOG"
exit 0
