#!/usr/bin/env bash
set -u
set -o pipefail

BASE_URL="${BASE_URL:-http://127.0.0.1:8020}"
PGHOST="${PGHOST:-192.168.1.110}"
PGUSER="${PGUSER:-clientflow}"
PGDATABASE="${PGDATABASE:-clientflow}"
TEST_TAG="e2e-$(date +%Y%m%d-%H%M%S)"
CONTACT_ID="${TEST_TAG}-contact"

PASS=0
FAIL=0

ok() { PASS=$((PASS+1)); echo "✅ $*"; }
fail() { FAIL=$((FAIL+1)); echo "❌ $*"; }

if [ -z "${PGPASSWORD:-}" ]; then
  echo "Define primeiro: export PGPASSWORD='password_da_bd'"
  exit 2
fi

psql_q() {
  PGPASSWORD="$PGPASSWORD" psql -h "$PGHOST" -U "$PGUSER" -d "$PGDATABASE" -Atc "$1"
}

request() {
  NAME="$1"
  EXPECT="$2"
  shift 2

  echo
  echo "=============================="
  echo "$NAME"
  echo "------------------------------"

  BODY="$(mktemp)"
  CODE="$(curl -sS -o "$BODY" -w "%{http_code}" "$@" || true)"

  echo "HTTP $CODE"

  if echo "$EXPECT" | grep -qw "$CODE"; then
    ok "$NAME"
  else
    fail "$NAME esperado [$EXPECT], recebeu HTTP $CODE"
    echo "Body:"
    cat "$BODY"
    echo
  fi

  LAST_BODY="$BODY"
  LAST_CODE="$CODE"
}

json_get() {
  FILE="$1"
  KEY="$2"
  python - "$FILE" "$KEY" <<'PY'
import json, sys
path, key = sys.argv[1], sys.argv[2]
try:
    data = json.load(open(path, encoding="utf-8"))
except Exception:
    print("")
    raise SystemExit

cur = data
for part in key.split("."):
    if isinstance(cur, dict):
        cur = cur.get(part)
    else:
        cur = None
        break

print("" if cur is None else cur)
PY
}

echo "============================================================"
echo "ClientFlow E2E"
echo "BASE_URL=$BASE_URL"
echo "TEST_TAG=$TEST_TAG"
echo "============================================================"

echo
echo "== 0. BD =="

DB_OK="$(psql_q "SELECT current_database() || ':' || current_user;")"
if [ -n "$DB_OK" ]; then
  ok "BD OK: $DB_OK"
else
  fail "Falha ligação BD"
  exit 2
fi

for T in raw_events messages action_runs tasks opportunities opportunity_events products opportunity_items operation_links; do
  EXISTS="$(psql_q "SELECT to_regclass('public.$T') IS NOT NULL;")"
  if [ "$EXISTS" = "t" ]; then
    ok "Tabela existe: $T"
  else
    fail "Tabela em falta: $T"
  fi
done

PRODUCT_ID="$(psql_q "SELECT id FROM products WHERE active=true ORDER BY name LIMIT 1;")"
if [ -n "$PRODUCT_ID" ]; then
  ok "Produto para teste: $PRODUCT_ID"
else
  fail "Sem produto ativo para teste"
fi

echo
echo "== 1. Páginas principais =="

request "GET /" "200" "$BASE_URL/"
request "GET /tasks" "200" "$BASE_URL/tasks"
request "GET /opportunities" "200" "$BASE_URL/opportunities"
request "GET /products" "200" "$BASE_URL/products"
request "GET /orders" "200" "$BASE_URL/orders"
request "GET /finance" "200" "$BASE_URL/finance"
request "GET /customers" "200" "$BASE_URL/customers"

echo
echo "== 2. Analyze SEND_INFO =="

request "POST /analyze SEND_INFO" "200" \
  -X POST "$BASE_URL/analyze" \
  -H "Content-Type: application/json" \
  -d "{
    \"last_customer_message\": \"Enviar informação detalhada sobre carregador.\",
    \"previous_context\": \"Assunto: Carregador\",
    \"source\": \"e2e_test\",
    \"conversation_id\": \"$TEST_TAG-info\",
    \"contact_id\": \"$CONTACT_ID\"
  }"

TASK_INFO_ID="$(json_get "$LAST_BODY" "task_id")"
if [ -z "$TASK_INFO_ID" ]; then
  TASK_INFO_ID="$(psql_q "SELECT id FROM tasks WHERE conversation_id='$TEST_TAG-info' ORDER BY created_at DESC LIMIT 1;")"
fi

if [ -n "$TASK_INFO_ID" ]; then
  ok "Task criada: $TASK_INFO_ID"
else
  fail "Task SEND_INFO não criada"
fi

OPP_INFO_ID="$(psql_q "SELECT opportunity_id FROM tasks WHERE id::text='$TASK_INFO_ID' LIMIT 1;")"
if [ -n "$OPP_INFO_ID" ]; then
  ok "Oportunidade criada/ligada: $OPP_INFO_ID"
else
  fail "Sem oportunidade ligada à task"
fi

if [ -n "$TASK_INFO_ID" ]; then
  request "GET task criada" "200 302 303" "$BASE_URL/tasks/$TASK_INFO_ID"
fi

if [ -n "$OPP_INFO_ID" ]; then
  request "GET oportunidade criada" "200" "$BASE_URL/opportunities/$OPP_INFO_ID"
fi

echo
echo "== 3. Produto na oportunidade =="

if [ -n "$OPP_INFO_ID" ] && [ -n "$PRODUCT_ID" ]; then
  request "POST adicionar produto" "302 303" \
    -X POST "$BASE_URL/opportunities/$OPP_INFO_ID/items/add" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    --data-urlencode "product_id=$PRODUCT_ID" \
    --data-urlencode "quantity=1" \
    --data-urlencode "unit_price=" \
    --data-urlencode "discount_amount=0" \
    --data-urlencode "status=INTERESTED"

  ITEM_ID="$(psql_q "SELECT id FROM opportunity_items WHERE opportunity_id::text='$OPP_INFO_ID' ORDER BY created_at DESC LIMIT 1;")"
  if [ -n "$ITEM_ID" ]; then
    ok "Produto adicionado: $ITEM_ID"
  else
    fail "Produto não foi adicionado"
  fi
fi

echo
echo "== 4. Stage oportunidade =="

if [ -n "$OPP_INFO_ID" ]; then
  request "POST stage INFO_SENT" "302 303" \
    -X POST "$BASE_URL/opportunities/$OPP_INFO_ID/stage" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    --data-urlencode "stage=INFO_SENT" \
    --data-urlencode "note=E2E informação enviada"

  STAGE="$(psql_q "SELECT stage FROM opportunities WHERE id::text='$OPP_INFO_ID' LIMIT 1;")"
  if [ "$STAGE" = "INFO_SENT" ]; then
    ok "Stage INFO_SENT confirmado"
  else
    fail "Stage esperado INFO_SENT, recebido $STAGE"
  fi
fi

echo
echo "== 5. Complete task com nota =="

if [ -n "$TASK_INFO_ID" ]; then
  request "POST complete-with-note" "302 303" \
    -X POST "$BASE_URL/tasks/$TASK_INFO_ID/complete-with-note" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    --data-urlencode "done_note=E2E tarefa concluída" \
    --data-urlencode "done_note_extra=teste automático"

  STATUS="$(psql_q "SELECT status FROM tasks WHERE id::text='$TASK_INFO_ID' LIMIT 1;")"
  if [ "$STATUS" = "done" ]; then
    ok "Task concluída"
  else
    fail "Task deveria estar done, está $STATUS"
  fi
fi

echo

echo "== 6. Cockpit operacional com workflow guard =="

if [ -n "$OPP_INFO_ID" ]; then

  echo
  echo "-- 6.1 Bloqueio esperado: pagamento antes de pró-forma --"

  request "POST operation payment_confirmed antes de pró-forma" "409" \
    -X POST "$BASE_URL/opportunities/$OPP_INFO_ID/operations/payment_confirmed" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    --data-urlencode "note=E2E bloqueio esperado"

  echo
  echo "-- 6.2 Fluxo correto até venda Odoo --"

  request "POST operation jasmin_proforma" "302 303" \
    -X POST "$BASE_URL/opportunities/$OPP_INFO_ID/operations/jasmin_proforma" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    --data-urlencode "external_id=$TEST_TAG-proforma" \
    --data-urlencode "external_name=PF-$TEST_TAG" \
    --data-urlencode "external_url=https://jasmin.blif.pt/e2e/proforma" \
    --data-urlencode "note=E2E pró-forma emitida"

  request "POST operation payment_confirmed" "302 303" \
    -X POST "$BASE_URL/opportunities/$OPP_INFO_ID/operations/payment_confirmed" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    --data-urlencode "note=E2E pagamento confirmado"

  request "POST operation odoo_sale_order" "302 303" \
    -X POST "$BASE_URL/opportunities/$OPP_INFO_ID/operations/odoo_sale_order" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    --data-urlencode "external_id=$TEST_TAG-sale-order" \
    --data-urlencode "external_name=SO-$TEST_TAG" \
    --data-urlencode "external_url=https://odoo.plixin.com/web#id=999999&model=sale.order&view_type=form" \
    --data-urlencode "note=E2E venda Odoo registada"

  echo
  echo "-- 6.3 Bloqueio esperado: Packlink antes de fatura/Odoo pronto --"

  request "POST operation packlink_shipment bloqueado" "409" \
    -X POST "$BASE_URL/opportunities/$OPP_INFO_ID/operations/packlink_shipment" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    --data-urlencode "external_id=$TEST_TAG-packlink-blocked" \
    --data-urlencode "external_name=PACKLINK-BLOQUEADO" \
    --data-urlencode "note=E2E bloqueio packlink esperado"

  echo
  echo "-- 6.4 Simular Odoo pronto para despacho no teste --"

  PGPASSWORD="$PGPASSWORD" psql -h "$PGHOST" -U "$PGUSER" -d "$PGDATABASE" -c "
  INSERT INTO operation_links (
    opportunity_id,
    system,
    external_type,
    external_id,
    external_name,
    status,
    payload,
    last_synced_at,
    updated_at
  )
  VALUES (
    '$OPP_INFO_ID',
    'odoo',
    'physical_status',
    '$TEST_TAG-physical-ready',
    'Estado físico E2E',
    'ready_to_ship',
    jsonb_build_object(
      'label', 'Pronta para despacho',
      'reason', 'Simulação E2E: encomenda pronta.',
      'next_action', 'Criar envio Packlink.',
      'ready_to_ship', true,
      'sale_order', jsonb_build_object('id', 999999, 'name', 'SO-' || '$TEST_TAG'),
      'pickings', '[]'::jsonb,
      'productions', '[]'::jsonb
    ),
    now(),
    now()
  )
  ON CONFLICT (opportunity_id, system, external_type)
  DO UPDATE SET
    external_id = EXCLUDED.external_id,
    external_name = EXCLUDED.external_name,
    status = EXCLUDED.status,
    payload = EXCLUDED.payload,
    last_synced_at = now(),
    updated_at = now();
  "

  request "POST operation odoo_physical_validated" "302 303" \
    -X POST "$BASE_URL/opportunities/$OPP_INFO_ID/operations/odoo_physical_validated" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    --data-urlencode "external_id=$TEST_TAG-physical-validated" \
    --data-urlencode "external_name=Validação física E2E" \
    --data-urlencode "note=E2E encomenda física validada"

  request "POST operation jasmin_invoice" "302 303" \
    -X POST "$BASE_URL/opportunities/$OPP_INFO_ID/operations/jasmin_invoice" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    --data-urlencode "external_id=$TEST_TAG-invoice" \
    --data-urlencode "external_name=FT-$TEST_TAG" \
    --data-urlencode "external_url=https://jasmin.blif.pt/e2e/invoice" \
    --data-urlencode "note=E2E fatura emitida"

  request "POST operation packlink_shipment" "302 303" \
    -X POST "$BASE_URL/opportunities/$OPP_INFO_ID/operations/packlink_shipment" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    --data-urlencode "external_id=$TEST_TAG-shipment" \
    --data-urlencode "external_name=PACKLINK-$TEST_TAG" \
    --data-urlencode "external_url=https://pro.packlink.pt/e2e/shipment" \
    --data-urlencode "note=E2E envio criado"

  request "POST operation tracking_sent" "302 303" \
    -X POST "$BASE_URL/opportunities/$OPP_INFO_ID/operations/tracking_sent" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    --data-urlencode "external_id=$TEST_TAG-tracking" \
    --data-urlencode "external_name=TRK-$TEST_TAG" \
    --data-urlencode "external_url=https://tracking.example/e2e" \
    --data-urlencode "note=E2E tracking enviado"

  request "POST operation delivered" "302 303" \
    -X POST "$BASE_URL/opportunities/$OPP_INFO_ID/operations/delivered" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    --data-urlencode "external_id=$TEST_TAG-delivered" \
    --data-urlencode "external_name=Entrega E2E" \
    --data-urlencode "note=E2E entregue"

  LINKS="$(psql_q "SELECT count(*) FROM operation_links WHERE opportunity_id::text='$OPP_INFO_ID';")"
  if [ "$LINKS" -ge 8 ]; then
    ok "operation_links criados: $LINKS"
  else
    fail "operation_links insuficientes: $LINKS"
  fi

  FINAL_STAGE="$(psql_q "SELECT stage FROM opportunities WHERE id::text='$OPP_INFO_ID' LIMIT 1;")"
  if [ "$FINAL_STAGE" = "WON" ]; then
    ok "Stage final WON"
  else
    fail "Stage final esperado WON, recebido $FINAL_STAGE"
  fi

else
  fail "Sem OPP_INFO_ID; não foi possível testar cockpit operacional"
fi

echo "== 7. Resumo =="

psql -h "$PGHOST" -U "$PGUSER" -d "$PGDATABASE" -c "
SELECT action_code, status, count(*)
FROM tasks
GROUP BY action_code, status
ORDER BY action_code, status;
"

psql -h "$PGHOST" -U "$PGUSER" -d "$PGDATABASE" -c "
SELECT stage, status, count(*)
FROM opportunities
GROUP BY stage, status
ORDER BY stage, status;
"

psql -h "$PGHOST" -U "$PGUSER" -d "$PGDATABASE" -c "
SELECT system, external_type, status, count(*)
FROM operation_links
GROUP BY system, external_type, status
ORDER BY system, external_type, status;
"

echo
echo "== 8. Limpeza ignorada para inspeção manual =="


echo
echo "============================================================"
echo "PASS=$PASS"
echo "FAIL=$FAIL"
echo "============================================================"

if [ "$FAIL" -eq 0 ]; then
  echo "✅ E2E concluído sem falhas críticas"
  exit 0
else
  echo "❌ E2E encontrou falhas"
  exit 1
fi
