#!/bin/bash
BASE="http://localhost:3000/api/v1"
RESULTS_FILE="/tmp/hms_test_results.txt"
> "$RESULTS_FILE"

# Login first
LOGIN_RESP=$(curl -s "$BASE/auth/login" -H "Content-Type: application/json" -d '{"username":"admin","password":"Admin@2026"}')
TOKEN=$(echo "$LOGIN_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['access_token'])" 2>/dev/null)
REFRESH_TOKEN=$(echo "$LOGIN_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['refresh_token'])" 2>/dev/null)

if [ -z "$TOKEN" ]; then
  echo "LOGIN FAILED - cannot continue"
  exit 1
fi

echo "Login successful, TOKEN length: ${#TOKEN}"

# Helper function
test_endpoint() {
  local method=$1
  local url=$2
  local data="$3"
  local label=$4
  local expected="$5"

  local resp_body=""
  local http_code=""

  if [ "$method" = "GET" ]; then
    RESP=$(curl -s -w "\nHTTP_CODE:%{http_code}" "$BASE$url" \
      -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" 2>/dev/null)
  elif [ "$method" = "DELETE" ]; then
    RESP=$(curl -s -w "\nHTTP_CODE:%{http_code}" -X DELETE "$BASE$url" \
      -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" 2>/dev/null)
  else
    RESP=$(curl -s -w "\nHTTP_CODE:%{http_code}" -X "$method" "$BASE$url" \
      -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
      -d "$data" 2>/dev/null)
  fi

  http_code=$(echo "$RESP" | grep "HTTP_CODE:" | sed 's/HTTP_CODE://')
  resp_body=$(echo "$RESP" | grep -v "HTTP_CODE:")
  success=$(echo "$resp_body" | python3 -c "import sys,json; d=json.load(sys.stdin); print('true' if d.get('success') else 'false')" 2>/dev/null || echo "parse_error")

  local status="PASS"
  if [ -n "$expected" ]; then
    if [ "$http_code" != "$expected" ]; then
      status="FAIL"
    fi
  else
    if [ "$http_code" -ge 400 ] 2>/dev/null; then
      status="FAIL"
    fi
  fi

  echo "$status | $method $url | HTTP $http_code | success=$success | $label" >> "$RESULTS_FILE"

  # Return the body for chaining
  echo "$resp_body"
}

# ==========================================
# AUTH MODULE (24 endpoints)
# ==========================================
echo "=== AUTH MODULE TESTS ===" >> "$RESULTS_FILE"

# 1. POST /auth/login
echo "PASS | POST /auth/login | HTTP 200 | success=true | Login" >> "$RESULTS_FILE"

# 2. POST /auth/refresh
test_endpoint POST "/auth/refresh" "{\"refresh_token\":\"$REFRESH_TOKEN\"}" "Token refresh"

# Re-login since refresh may invalidate old token
LOGIN_RESP=$(curl -s "$BASE/auth/login" -H "Content-Type: application/json" -d '{"username":"admin","password":"Admin@2026"}')
TOKEN=$(echo "$LOGIN_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['access_token'])" 2>/dev/null)
REFRESH_TOKEN=$(echo "$LOGIN_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['refresh_token'])" 2>/dev/null)

# 3. POST /auth/logout - test last to keep token alive
echo "PENDING | POST /auth/logout | - | - | Logout (tested last)" >> "$RESULTS_FILE"

# 4. POST /auth/change-password (wrong password - expect 400 or error)
test_endpoint POST "/auth/change-password" '{"current_password":"wrong_password","new_password":"NewPass123!"}' "Change password wrong current" "400"

# 5. GET /users
USERS_RESP=$(test_endpoint GET "/users?page=1&page_size=10" "" "User list")

# 6. POST /users
RAND=$(date +%s)
CREATE_USER_RESP=$(test_endpoint POST "/users" "{\"username\":\"apitest_${RAND}\",\"password\":\"Test@2026pwd\",\"display_name\":\"API Test User\",\"email\":\"apitest_${RAND}@test.com\"}" "Create user")
USER_ID=$(echo "$CREATE_USER_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin).get('data',{}).get('id',''))" 2>/dev/null)
echo "  -> Created user: $USER_ID"

# 7. GET /users/{id}
if [ -n "$USER_ID" ]; then
  test_endpoint GET "/users/$USER_ID" "" "Get user detail"
fi

# 8. PUT /users/{id}
if [ -n "$USER_ID" ]; then
  test_endpoint PUT "/users/$USER_ID" '{"display_name":"API Test User Updated","email":"updated@test.com"}' "Update user"
fi

# 9. DELETE /users/{id}
if [ -n "$USER_ID" ]; then
  test_endpoint DELETE "/users/$USER_ID" "" "Delete user (soft)"
fi

# 10. POST /users/{id}/roles - need user id and role id
echo "PENDING | POST /users/{id}/roles | - | - | Assign roles (need user+role)" >> "$RESULTS_FILE"

# 11. POST /users/{id}/reset-password
echo "SKIP | POST /users/{id}/reset-password | - | - | Reset password (skip safety)" >> "$RESULTS_FILE"

# 12. GET /roles
ROLES_RESP=$(test_endpoint GET "/roles?page=1&page_size=10" "" "Role list")
ROLE_ID=$(echo "$ROLES_RESP" | python3 -c "import sys,json; items=json.load(sys.stdin).get('data',{}).get('items',[]); print(items[0]['id'] if items else '')" 2>/dev/null)
echo "  -> First role: $ROLE_ID"

# 13. POST /roles
CREATE_ROLE_RESP=$(test_endpoint POST "/roles" "{\"name\":\"API Test Role ${RAND}\",\"code\":\"api_test_${RAND}\",\"description\":\"Test role by API test\"}" "Create role")
NEW_ROLE_ID=$(echo "$CREATE_ROLE_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin).get('data',{}).get('id',''))" 2>/dev/null)
echo "  -> Created role: $NEW_ROLE_ID"

# 14. GET /roles/permissions => same as GET /permissions (tested later as #20)

# 15. GET /roles/{id}
if [ -n "$NEW_ROLE_ID" ]; then
  test_endpoint GET "/roles/$NEW_ROLE_ID" "" "Get role detail"
fi

# 16. PUT /roles/{id}
if [ -n "$NEW_ROLE_ID" ]; then
  test_endpoint PUT "/roles/$NEW_ROLE_ID" '{"name":"Updated API Test Role","description":"Updated"}' "Update role"
fi

# 17. DELETE /roles/{id}
if [ -n "$NEW_ROLE_ID" ]; then
  test_endpoint DELETE "/roles/$NEW_ROLE_ID" "" "Delete role"
fi

# 18. GET /roles/{id}/permissions
if [ -n "$ROLE_ID" ]; then
  test_endpoint GET "/roles/$ROLE_ID/permissions" "" "Get role permissions"
fi

# 19. POST /roles/{id}/permissions
if [ -n "$ROLE_ID" ]; then
  test_endpoint POST "/roles/$ROLE_ID/permissions" '{"permission_ids":["user.list","user.create"]}' "Assign permissions to role"
fi

# 20. GET /permissions
test_endpoint GET "/permissions" "" "Permission list"

# 21. GET /organizations
ORGS_RESP=$(test_endpoint GET "/organizations?page=1&page_size=10" "" "Organization list")

# 22. POST /organizations
CREATE_ORG_RESP=$(test_endpoint POST "/organizations" "{\"name\":\"API Test Org ${RAND}\",\"code\":\"TEST_ORG_${RAND}\",\"description\":\"Test org\"}" "Create organization")
ORG_ID=$(echo "$CREATE_ORG_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin).get('data',{}).get('id',''))" 2>/dev/null)
echo "  -> Created org: $ORG_ID"

# 23. PUT /organizations/{id}
if [ -n "$ORG_ID" ]; then
  test_endpoint PUT "/organizations/$ORG_ID" '{"name":"Updated Org","description":"Updated"}' "Update organization"
fi

# 24. DELETE /organizations/{id}
if [ -n "$ORG_ID" ]; then
  test_endpoint DELETE "/organizations/$ORG_ID" "" "Delete organization"
fi

# ==========================================
# CONFIG MODULE (19 endpoints)
# ==========================================
echo "" >> "$RESULTS_FILE"
echo "=== CONFIG MODULE TESTS ===" >> "$RESULTS_FILE"

# 1. GET /config/dictionaries
DICTS_RESP=$(test_endpoint GET "/config/dictionaries?page=1&page_size=10" "" "Dictionary list")

# 2. POST /config/dictionaries
CREATE_DICT_RESP=$(test_endpoint POST "/config/dictionaries" "{\"name\":\"API Test Dict ${RAND}\",\"code\":\"api_test_dict_${RAND}\",\"description\":\"Test dictionary\"}" "Create dictionary")
DICT_ID=$(echo "$CREATE_DICT_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin).get('data',{}).get('id',''))" 2>/dev/null)

# 3. PUT /config/dictionaries/{id}
if [ -n "$DICT_ID" ]; then
  test_endpoint PUT "/config/dictionaries/$DICT_ID" '{"name":"Updated Dict","description":"Updated"}' "Update dictionary"
fi

# 4. DELETE /config/dictionaries/{id}
if [ -n "$DICT_ID" ]; then
  test_endpoint DELETE "/config/dictionaries/$DICT_ID" "" "Delete dictionary"
fi

# 5. GET /config/dictionaries/items
test_endpoint GET "/config/dictionaries/items?page=1&page_size=10" "" "Dictionary items list"

# Create another dict for item tests
CREATE_DICT_RESP2=$(test_endpoint POST "/config/dictionaries" "{\"name\":\"API Test Dict Items ${RAND}\",\"code\":\"api_test_items_${RAND}\"}" "Create dict for item test")
DICT_ID2=$(echo "$CREATE_DICT_RESP2" | python3 -c "import sys,json; print(json.load(sys.stdin).get('data',{}).get('id',''))" 2>/dev/null)

# 6. POST /config/dictionaries/{dict_id}/items
if [ -n "$DICT_ID2" ]; then
  CREATE_ITEM_RESP=$(test_endpoint POST "/config/dictionaries/$DICT_ID2/items" '{"label":"Test Item","value":"test_value","sort_order":1}' "Create dictionary item")
  ITEM_ID=$(echo "$CREATE_ITEM_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin).get('data',{}).get('id',''))" 2>/dev/null)

  # 7. PUT /config/dictionaries/{dict_id}/items/{item_id}
  if [ -n "$ITEM_ID" ]; then
    test_endpoint PUT "/config/dictionaries/$DICT_ID2/items/$ITEM_ID" '{"label":"Updated Item","value":"updated_value"}' "Update dictionary item"

    # 8. DELETE /config/dictionaries/{dict_id}/items/{item_id}
    test_endpoint DELETE "/config/dictionaries/$DICT_ID2/items/$ITEM_ID" "" "Delete dictionary item"
  fi
fi

# 9. GET /config/menus
test_endpoint GET "/config/menus" "" "Menu list"

# 10. POST /config/menus
CREATE_MENU_RESP=$(test_endpoint POST "/config/menus" '{"name":"API Test Menu","path":"/test","icon":"test","sort_order":999,"type":"menu"}' "Create menu")
MENU_ID=$(echo "$CREATE_MENU_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin).get('data',{}).get('id',''))" 2>/dev/null)

# 11. PUT /config/menus/{id}
if [ -n "$MENU_ID" ]; then
  test_endpoint PUT "/config/menus/$MENU_ID" '{"name":"Updated Menu","path":"/test-updated"}' "Update menu"
fi

# 12. DELETE /config/menus/{id}
if [ -n "$MENU_ID" ]; then
  test_endpoint DELETE "/config/menus/$MENU_ID" "" "Delete menu"
fi

# 13. GET /menus/user
test_endpoint GET "/menus/user" "" "User menu tree"

# 14. GET /config/settings/{key}
test_endpoint GET "/config/settings/system.title" "" "Get setting by key"

# 15. PUT /config/settings/{key}
test_endpoint PUT "/config/settings/system.title" '{"value":"HMS Health Platform"}' "Update setting"

# 16. GET /config/numbering-rules
test_endpoint GET "/config/numbering-rules?page=1&page_size=10" "" "Numbering rules list"

# 17. POST /config/numbering-rules
CREATE_NUM_RESP=$(test_endpoint POST "/config/numbering-rules" "{\"name\":\"API Test Rule ${RAND}\",\"code\":\"TEST_NUM_${RAND}\",\"prefix\":\"TST\",\"pattern\":\"{YYYY}{MM}-{SEQ}\",\"seq_length\":4}" "Create numbering rule")
NUM_RULE_ID=$(echo "$CREATE_NUM_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin).get('data',{}).get('id',''))" 2>/dev/null)

# 18. POST /config/numbering-rules/{id}/generate
if [ -n "$NUM_RULE_ID" ]; then
  test_endpoint POST "/config/numbering-rules/$NUM_RULE_ID/generate" "{}" "Generate number"
fi

# 19. GET /config/languages
test_endpoint GET "/config/languages" "" "Language list"

# ==========================================
# WORKFLOW MODULE (15 endpoints)
# ==========================================
echo "" >> "$RESULTS_FILE"
echo "=== WORKFLOW MODULE TESTS ===" >> "$RESULTS_FILE"

# 1. GET /workflow/definitions
test_endpoint GET "/workflow/definitions?page=1&page_size=10" "" "Workflow definitions list"

# 2. POST /workflow/definitions
BPMN='<?xml version="1.0" encoding="UTF-8"?><bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn"><bpmn:process id="Process_1" isExecutable="false"><bpmn:startEvent id="StartEvent_1"/><bpmn:endEvent id="EndEvent_1"/><bpmn:sequenceFlow id="Flow_1" sourceRef="StartEvent_1" targetRef="EndEvent_1"/></bpmn:process></bpmn:definitions>'
CREATE_WF_RESP=$(test_endpoint POST "/workflow/definitions" "{\"name\":\"API Test Workflow ${RAND}\",\"description\":\"Test workflow\",\"bpmn_xml\":\"${BPMN}\"}" "Create workflow definition")
WF_DEF_ID=$(echo "$CREATE_WF_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin).get('data',{}).get('id',''))" 2>/dev/null)

# 3. GET /workflow/definitions/{id}
if [ -n "$WF_DEF_ID" ]; then
  test_endpoint GET "/workflow/definitions/$WF_DEF_ID" "" "Get workflow definition detail"

  # 4. PUT /workflow/definitions/{id}
  test_endpoint PUT "/workflow/definitions/$WF_DEF_ID" '{"name":"Updated Workflow","description":"Updated"}' "Update workflow definition"

  # 5. POST /workflow/definitions/{id}/publish
  test_endpoint POST "/workflow/definitions/$WF_DEF_ID/publish" "{}" "Publish workflow"
fi

# 6. POST /workflow/definitions/{id}/deprecate - create and publish first
# Re-create for deprecate test
WF_DEF2_RESP=$(test_endpoint POST "/workflow/definitions" "{\"name\":\"API Test Workflow Dep ${RAND}\",\"description\":\"For deprecate\",\"bpmn_xml\":\"${BPMN}\"}" "Create workflow for deprecate")
WF_DEF2_ID=$(echo "$WF_DEF2_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin).get('data',{}).get('id',''))" 2>/dev/null)
if [ -n "$WF_DEF2_ID" ]; then
  test_endpoint POST "/workflow/definitions/$WF_DEF2_ID/publish" "{}" "Publish for deprecate"
  test_endpoint POST "/workflow/definitions/$WF_DEF2_ID/deprecate" "{}" "Deprecate workflow"
fi

# 7. POST /workflow/instances
WF_INST_RESP=$(test_endpoint POST "/workflow/instances" "{\"definition_id\":\"${WF_DEF_ID}\",\"variables\":{}}" "Start workflow instance")
WF_INST_ID=$(echo "$WF_INST_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin).get('data',{}).get('id',''))" 2>/dev/null)

# 8. GET /workflow/instances
test_endpoint GET "/workflow/instances?page=1&page_size=10" "" "Workflow instances list"

# 9. GET /workflow/instances/{id}
if [ -n "$WF_INST_ID" ]; then
  test_endpoint GET "/workflow/instances/$WF_INST_ID" "" "Get instance detail"

  # 10. POST /workflow/instances/{id}/suspend
  test_endpoint POST "/workflow/instances/$WF_INST_ID/suspend" "{}" "Suspend instance"

  # 11. POST /workflow/instances/{id}/resume
  test_endpoint POST "/workflow/instances/$WF_INST_ID/resume" "{}" "Resume instance"

  # 12. POST /workflow/instances/{id}/terminate
  test_endpoint POST "/workflow/instances/$WF_INST_ID/terminate" "{}" "Terminate instance"
fi

# 13. GET /workflow/tasks/pending
test_endpoint GET "/workflow/tasks/pending?page=1&page_size=10" "" "Pending tasks"

# 14. GET /workflow/tasks/completed
test_endpoint GET "/workflow/tasks/completed?page=1&page_size=10" "" "Completed tasks"

# 15. POST /workflow/tasks/{id}/complete
PENDING_TASK_RESP=$(test_endpoint GET "/workflow/tasks/pending?page=1&page_size=1" "" "Get pending task for complete test")
TASK_ID=$(echo "$PENDING_TASK_RESP" | python3 -c "import sys,json; items=json.load(sys.stdin).get('data',{}).get('items',[]); print(items[0]['id'] if items else '')" 2>/dev/null)
if [ -n "$TASK_ID" ]; then
  test_endpoint POST "/workflow/tasks/$TASK_ID/complete" '{"variables":{}}' "Complete task"
else
  echo "SKIP | POST /workflow/tasks/{id}/complete | - | - | No pending task available" >> "$RESULTS_FILE"
fi

# ==========================================
# MESSAGE MODULE (10 endpoints)
# ==========================================
echo "" >> "$RESULTS_FILE"
echo "=== MESSAGE MODULE TESTS ===" >> "$RESULTS_FILE"

# 1. GET /messages
test_endpoint GET "/messages?page=1&page_size=10" "" "Message list"

# 2. POST /messages
CREATE_MSG_RESP=$(test_endpoint POST "/messages" '{"title":"API Test Message","content":"Test message content","type":"system","recipient_type":"user"}' "Send message")
MSG_ID=$(echo "$CREATE_MSG_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin).get('data',{}).get('id',''))" 2>/dev/null)

# 3. GET /messages/unread-count
test_endpoint GET "/messages/unread-count" "" "Unread count"

# 4. PUT /messages/{id}/read
if [ -n "$MSG_ID" ]; then
  test_endpoint PUT "/messages/$MSG_ID/read" "{}" "Mark message read"
fi

# 5. PUT /messages/read-all
test_endpoint PUT "/messages/read-all" "{}" "Mark all read"

# 6. DELETE /messages/{id}
if [ -n "$MSG_ID" ]; then
  test_endpoint DELETE "/messages/$MSG_ID" "" "Delete message"
fi

# 7. GET /message-templates
test_endpoint GET "/message-templates?page=1&page_size=10" "" "Message templates list"

# 8. POST /message-templates
CREATE_TPL_RESP=$(test_endpoint POST "/message-templates" "{\"name\":\"API Test Template ${RAND}\",\"code\":\"test_tpl_${RAND}\",\"content\":\"Hello {{name}}\",\"channel\":\"system\"}" "Create template")
TPL_ID=$(echo "$CREATE_TPL_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin).get('data',{}).get('id',''))" 2>/dev/null)

# 9. PUT /message-templates/{id}
if [ -n "$TPL_ID" ]; then
  test_endpoint PUT "/message-templates/$TPL_ID" '{"name":"Updated Template","content":"Hello {{name}}, updated"}' "Update template"
fi

# 10. GET /message-subscriptions
test_endpoint GET "/message-subscriptions?page=1&page_size=10" "" "Subscriptions list"

# ==========================================
# Final: Test logout
# ==========================================
test_endpoint POST "/auth/logout" "{}" "Logout"

# ==========================================
# SUMMARY
# ==========================================
echo "" >> "$RESULTS_FILE"
echo "=== SUMMARY ===" >> "$RESULTS_FILE"

TOTAL=$(grep -c "^PASS\|^FAIL\|^SKIP\|^PENDING" "$RESULTS_FILE")
PASSED=$(grep -c "^PASS" "$RESULTS_FILE")
FAILED=$(grep -c "^FAIL" "$RESULTS_FILE")
SKIPPED=$(grep -c "^SKIP" "$RESULTS_FILE")
PENDING=$(grep -c "^PENDING" "$RESULTS_FILE")

echo "Total: $TOTAL | Passed: $PASSED | Failed: $FAILED | Skipped: $SKIPPED | Pending: $PENDING" >> "$RESULTS_FILE"

echo ""
echo "==============================="
echo "Test completed."
echo "==============================="
cat "$RESULTS_FILE"
