#!/usr/bin/env bash
# Valley Insurance Partner API: end to end example script.
#
# What this does:
#   Runs the whole partner flow against the real API in one shot:
#     1. Fetch your account (GET /partner/me)
#     2. Look up a state you are enabled for (GET /partner/filing-states)
#     3. Get a price quote for a new business filing (POST /partner/calculate)
#     4. Upload an example document (POST /partner/upload-user-file + signed PUT)
#     5. Create a filing (POST /partner/create-filing)
#     6. Track the filing (GET /partner/{id})
#     7. List your filings and confirm it shows up (GET /partner/filings)
#
# Requirements:
#   bash, curl, and jq.
#
# How to run:
#   chmod +x try-valley-partner-api.sh
#   export PARTNER_KEY=your-key-here
#   ./try-valley-partner-api.sh
#
# WARNING: this script creates a REAL filing in your account. It uses
# obvious TEST values (policy number prefixed "TEST-", insured name
# prefixed "TEST -") so you can find it afterward and delete it if you
# don't want it kept around.

set -euo pipefail

if ! command -v jq >/dev/null 2>&1; then
  echo "This script requires jq, but it was not found on your PATH." >&2
  echo "Install it (e.g. 'brew install jq' or 'apt-get install jq') and try again." >&2
  exit 1
fi

if ! command -v curl >/dev/null 2>&1; then
  echo "This script requires curl, but it was not found on your PATH." >&2
  echo "Install it and try again." >&2
  exit 1
fi

if [ -z "${PARTNER_KEY:-}" ]; then
  echo "Missing PARTNER_KEY environment variable." >&2
  echo "" >&2
  echo "Set it before running this script, for example:" >&2
  echo "  export PARTNER_KEY=your-key-here" >&2
  echo "  ./try-valley-partner-api.sh" >&2
  echo "" >&2
  echo "Need a key? Contact Gina Doyle at gina@valleyinsllc.com." >&2
  exit 1
fi

BASE_URL="${BASE_URL:-https://api.valleyinsllc.com/api/v1}"

TMP_FILE="$(mktemp)"
trap 'rm -f "$TMP_FILE"' EXIT

# Small helper: sets the PartnerKey header, JSON encodes the body if given,
# checks the HTTP status, and on failure prints the status and response
# body before exiting. Prints the response body to stdout on success.
api() {
  local method="$1"
  local path="$2"
  local body="${3:-}"
  local response status http_body

  if [ -n "$body" ]; then
    response=$(curl -sS -w '\n%{http_code}' -X "$method" \
      -H "PartnerKey: $PARTNER_KEY" \
      -H "Content-Type: application/json" \
      -d "$body" \
      "${BASE_URL}${path}")
  else
    response=$(curl -sS -w '\n%{http_code}' -X "$method" \
      -H "PartnerKey: $PARTNER_KEY" \
      -H "Content-Type: application/json" \
      "${BASE_URL}${path}")
  fi

  status="${response##*$'\n'}"
  http_body="${response%$'\n'*}"

  if [ "$status" -lt 200 ] || [ "$status" -ge 300 ]; then
    echo "" >&2
    echo "Request failed: $method $path" >&2
    echo "Status: $status" >&2
    echo "Response: $http_body" >&2
    echo "" >&2
    echo "Check your PARTNER_KEY and try again. If the problem" >&2
    echo "persists, contact gina@valleyinsllc.com." >&2
    exit 1
  fi

  printf '%s' "$http_body"
}

echo "Valley Insurance Partner API: end to end example"
echo "Base URL: $BASE_URL"
echo ""

# Step 1: who am I, and which states can I file in?
echo "Step 1/7: fetching your account (GET /partner/me)"
me="$(api GET /partner/me)"
name="$(echo "$me" | jq -r '[.firstName, .lastName] | map(select(. != null and . != "")) | join(" ")')"
email="$(echo "$me" | jq -r '.email')"
if [ -z "$name" ]; then
  name="$email"
fi
enabled_states_csv="$(echo "$me" | jq -r '.enabledStates | join(", ")')"
echo "  You are: $name ($email)"
echo "  Enabled states: ${enabled_states_csv:-(none)}"
echo ""

enabled_states_count="$(echo "$me" | jq -r '.enabledStates | length')"
if [ "$enabled_states_count" -eq 0 ]; then
  echo "Your account is not enabled for any states yet. Contact"
  echo "gina@valleyinsllc.com to request access."
  exit 0
fi

# Prefer TX since it's the most commonly enabled state, otherwise take
# whatever is first so this script works for any partner.
has_tx="$(echo "$me" | jq -r '.enabledStates | index("TX") != null')"
if [ "$has_tx" = "true" ]; then
  chosen_state="TX"
else
  chosen_state="$(echo "$me" | jq -r '.enabledStates[0]')"
fi
echo "Chosen state for this walkthrough: $chosen_state"
echo ""

# Step 2: look up the state's required documents.
echo "Step 2/7: looking up filing states (GET /partner/filing-states)"
filing_states="$(api GET /partner/filing-states)"
filing_state="$(echo "$filing_states" | jq -c --arg state "$chosen_state" '.[] | select(.stateAbbr==$state)')"

if [ -z "$filing_state" ]; then
  echo "Could not find a filing state entry for $chosen_state." >&2
  echo "This is unexpected since it was in your enabledStates." >&2
  echo "Contact gina@valleyinsllc.com." >&2
  exit 1
fi

filing_state_id="$(echo "$filing_state" | jq -r '.id')"
state_name="$(echo "$filing_state" | jq -r '.name')"
state_abbr="$(echo "$filing_state" | jq -r '.stateAbbr')"
echo "  State: $state_name ($state_abbr)"
echo "  Filing state id: $filing_state_id"
echo "  Required documents for new business filings:"
required_docs_count="$(echo "$filing_state" | jq -r '(.filesNb // []) | length')"
if [ "$required_docs_count" -eq 0 ]; then
  echo "    (none listed)"
else
  while IFS= read -r doc; do
    echo "    - $doc"
  done < <(echo "$filing_state" | jq -r '(.filesNb // [])[].name')
fi
# Note: filingState.descriptionNb is an HTML requirements checklist meant
# to be rendered in a UI, not printed as plain text. We skip printing it
# here; see the docs for how to render it.
echo ""

# Step 3: get a price quote.
echo "Step 3/7: getting a price quote (POST /partner/calculate)"
quote_body="$(jq -n --arg stateAbbr "$chosen_state" \
  '{filingType: "NEW_BUSINESS", stateAbbr: $stateAbbr, premium: 10000}')"
quote="$(api POST /partner/calculate "$quote_body")"
total="$(echo "$quote" | jq -r '.total')"
echo "  Quote for a \$10,000 new business premium in $chosen_state:"
echo "    Total: \$$total"
echo ""

# Step 4: upload an example document.
echo "Step 4/7: uploading an example document (POST /partner/upload-user-file)"
upload_body='{"fileName": "valley-api-example.txt"}'
upload="$(api POST /partner/upload-user-file "$upload_body")"
upload_url="$(echo "$upload" | jq -r '.uploadUrl')"
upload_file_name="$(echo "$upload" | jq -r '.fileName')"
storage_path="$(echo "$upload" | jq -r '.storagePath')"

printf 'Valley Partner API example document\n' > "$TMP_FILE"
byte_count="$(wc -c < "$TMP_FILE" | tr -d ' ')"

# CRITICAL: the signed URL is generated for application/octet-stream.
# Any other Content-Type makes GCS reject the PUT with 403. This is a
# raw PUT to a signed GCS URL, so it does NOT carry a PartnerKey header,
# only Content-Type.
put_response=$(curl -sS -w '\n%{http_code}' -X PUT \
  -H "Content-Type: application/octet-stream" \
  --data-binary @"$TMP_FILE" \
  "$upload_url")
put_status="${put_response##*$'\n'}"
put_body="${put_response%$'\n'*}"

if [ "$put_status" -lt 200 ] || [ "$put_status" -ge 300 ]; then
  echo "" >&2
  echo "Upload PUT failed." >&2
  echo "Status: $put_status" >&2
  echo "Response: $put_body" >&2
  exit 1
fi

echo "  Uploaded $byte_count bytes to the signed URL."
echo "  Storage path: $storage_path"
echo ""

# Step 5: create the filing. Deliberately uses obvious TEST values so
# this is easy to find and delete afterward.
echo "Step 5/7: creating the filing (POST /partner/create-filing)"
policy_number="TEST-$(date +%s)"
effective_date="$(date +%Y-%m-%d)"
create_filing_body="$(jq -n \
  --arg filingStateId "$filing_state_id" \
  --arg policyNumber "$policy_number" \
  --arg policyEffectiveDate "$effective_date" \
  --arg fileName "$upload_file_name" \
  --arg filePath "$storage_path" \
  '{
    filingType: "NEW_BUSINESS",
    filingStateId: $filingStateId,
    policyNumber: $policyNumber,
    insuredsName: "TEST - Valley API Example",
    carriersName: "TEST Carrier",
    policyEffectiveDate: $policyEffectiveDate,
    premium: 10000,
    files: [
      {
        name: "Example document",
        fileName: $fileName,
        filePath: $filePath
      }
    ]
  }')"
filing="$(api POST /partner/create-filing "$create_filing_body")"
filing_id="$(echo "$filing" | jq -r '.id')"
filing_status="$(echo "$filing" | jq -r '.status')"
echo "  Created filing $filing_id"
echo "  Status: $filing_status"
echo ""

# Step 6: track the filing.
echo "Step 6/7: tracking the filing (GET /partner/$filing_id)"
tracked="$(api GET "/partner/$filing_id")"
tracked_status="$(echo "$tracked" | jq -r '.status')"
echo "  Current status: $tracked_status"
echo ""

# Step 7: list filings and confirm the new one shows up.
echo "Step 7/7: listing your filings (GET /partner/filings?limit=5)"
list="$(api GET /partner/filings?limit=5)"
list_total="$(echo "$list" | jq -r '.total')"
found="$(echo "$list" | jq -r --arg id "$filing_id" '[.items[] | select(.id == $id)] | length > 0')"
echo "  Total filings on your account: $list_total"
if [ "$found" = "true" ]; then
  echo "  Found the new filing ($filing_id) in the latest page of results."
else
  echo "  The new filing did not appear in the latest page (it may be further back)."
fi
echo ""

echo "Done."
echo "  Filing id: $filing_id"
echo "  Policy number: TEST-... (search for \"TEST\" to find it later)"
echo "  This was a real filing. Delete it if you do not want to keep it."
