#!/usr/bin/env bash

set -euo pipefail

BASE_URL="${LOCAL_BACKEND_BASE_URL:-http://127.0.0.1:3001}"
TOKEN_URL="${LOCAL_BACKEND_TOKEN_URL:-${BASE_URL}/services/oauth2/token}"
API_VERSION="${REST_API_API_VERSION:-v63.0}"
CLIENT_ID="${LOCAL_BACKEND_CLIENT_ID:-test-gosf-client}"
CLIENT_SECRET="${LOCAL_BACKEND_CLIENT_SECRET:-test-gosf-secret-123}"

DB_HOST="${TIDB_HOST:-127.0.0.1}"
DB_PORT="${TIDB_PORT:-4000}"
DB_USER="${TIDB_USER:-root}"
DB_PASSWORD="${TIDB_PASSWORD:-}"
DB_NAME="${TIDB_DATABASE:-nexuscrm}"

ensure_mysql_client_on_path() {
  if command -v mysql >/dev/null 2>&1; then
    return
  fi

  local candidate
  for candidate in \
    "/opt/homebrew/opt/mysql-client/bin/mysql" \
    "/usr/local/opt/mysql-client/bin/mysql"
  do
    if [[ -x "${candidate}" ]]; then
      export PATH="$(dirname "${candidate}"):${PATH}"
      return
    fi
  done
}

require_cmd() {
  if ! command -v "$1" >/dev/null 2>&1; then
    echo "missing required command: $1" >&2
    exit 1
  fi
}

require_cmd curl
require_cmd jq
ensure_mysql_client_on_path
require_cmd mysql

mysql_cmd() {
  mysql \
    -h "${DB_HOST}" \
    -P "${DB_PORT}" \
    -u "${DB_USER}" \
    ${DB_PASSWORD:+-p"${DB_PASSWORD}"} \
    -D "${DB_NAME}" \
    "$@"
}

db_scalar() {
  mysql_cmd -Nse "$1"
}

db_exec() {
  mysql_cmd -e "$1"
}

fetch_token() {
  curl -sS -X POST "${TOKEN_URL}" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    --data "grant_type=client_credentials&client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}" |
    jq -r ".access_token"
}

TOKEN="$(fetch_token)"
if [[ -z "${TOKEN}" || "${TOKEN}" == "null" ]]; then
  echo "failed to fetch access token from ${TOKEN_URL}" >&2
  exit 1
fi

post_json() {
  local path="$1"
  local payload="$2"
  local response_file
  local status

  response_file="$(mktemp)"
  status="$(curl -sS -o "${response_file}" -w "%{http_code}" \
    -X POST "${BASE_URL}${path}" \
    -H "Authorization: Bearer ${TOKEN}" \
    -H "Content-Type: application/json" \
    -H "Origin: ${BASE_URL}" \
    --data "${payload}")"

  case "${status}" in
    200|201)
      cat "${response_file}"
      ;;
    *)
      echo "POST ${path} failed with status ${status}" >&2
      cat "${response_file}" >&2
      rm -f "${response_file}"
      exit 1
      ;;
  esac

  rm -f "${response_file}"
}

ensure_object() {
  local api_name="$1"
  local payload="$2"
  local count

  count="$(db_scalar "SELECT COUNT(*) FROM _System_Object WHERE ApiName='${api_name}';")"
  if [[ "${count}" == "0" ]]; then
    echo "creating object ${api_name}"
    post_json "/services/data/${API_VERSION}/tooling/sobjects/CustomObject" "${payload}" >/dev/null
  else
    echo "object ${api_name} already exists"
  fi
}

ensure_field() {
  local object_api_name="$1"
  local field_api_name="$2"
  local payload="$3"
  local count

  count="$(db_scalar "SELECT COUNT(*) FROM _System_Field f JOIN _System_Object o ON f.ObjectId=o.Id WHERE o.ApiName='${object_api_name}' AND f.ApiName='${field_api_name}';")"
  if [[ "${count}" == "0" ]]; then
    echo "creating field ${object_api_name}.${field_api_name}"
    post_json "/services/data/${API_VERSION}/tooling/sobjects/CustomField" "${payload}" >/dev/null
  else
    echo "field ${object_api_name}.${field_api_name} already exists"
  fi
}

ensure_list_view() {
  local id="$1"
  local object_api_name="$2"
  local label="$3"
  local filter_expr="$4"
  local fields_json="$5"

  echo "seeding list view ${object_api_name}.${label} (${id})"
  db_exec "
    REPLACE INTO _System_ListView
      (Id, ObjectApiName, Label, FilterExpr, Fields, CreatedDate, LastModifiedDate)
    VALUES
      ('${id}', '${object_api_name}', '${label}', '${filter_expr}', '${fields_json}', NOW(), NOW());
  "
}

ensure_object "Account" "$(cat <<'JSON'
{"name":"Account","label":"Account","labelPlural":"Accounts","custom":false,"description":"Standard Account object for local contract verification"}
JSON
)"

ensure_object "Contact" "$(cat <<'JSON'
{"name":"Contact","label":"Contact","labelPlural":"Contacts","custom":false,"description":"Standard Contact object for local contract verification"}
JSON
)"

ensure_object "Opportunity" "$(cat <<'JSON'
{"name":"Opportunity","label":"Opportunity","labelPlural":"Opportunities","custom":false,"description":"Standard Opportunity object for local contract verification"}
JSON
)"

ensure_field "Account" "Portal_ID__c" "$(cat <<'JSON'
{"object_api_name":"Account","name":"Portal_ID__c","label":"Portal ID","type":"string","unique":true}
JSON
)"

ensure_field "Account" "External_Id__c" "$(cat <<'JSON'
{"object_api_name":"Account","name":"External_Id__c","label":"External ID","type":"string","unique":true}
JSON
)"

ensure_field "Account" "Industry" "$(cat <<'JSON'
{"object_api_name":"Account","name":"Industry","label":"Industry","type":"string"}
JSON
)"

ensure_field "Contact" "FirstName" "$(cat <<'JSON'
{"object_api_name":"Contact","name":"FirstName","label":"First Name","type":"string"}
JSON
)"

ensure_field "Contact" "LastName" "$(cat <<'JSON'
{"object_api_name":"Contact","name":"LastName","label":"Last Name","type":"string","required":true}
JSON
)"

ensure_field "Contact" "AccountId" "$(cat <<'JSON'
{"object_api_name":"Contact","name":"AccountId","label":"Account","type":"reference","referenceTo":["Account"],"relationshipName":"Contacts"}
JSON
)"

echo "normalizing Contact name-field metadata"
db_exec "
  UPDATE _System_Field f
  JOIN _System_Object o ON f.ObjectId=o.Id
  SET f.Required=0, f.IsNameField=0
  WHERE o.ApiName='Contact' AND f.ApiName='Name';

  UPDATE _System_Field f
  JOIN _System_Object o ON f.ObjectId=o.Id
  SET f.Required=1, f.IsNameField=1
  WHERE o.ApiName='Contact' AND f.ApiName='LastName';

  ALTER TABLE Contact MODIFY COLUMN Name VARCHAR(255) NULL;
"

echo "seeding fixed contract fixtures"
db_exec "
  REPLACE INTO Account
    (Id, OwnerId, CreatedById, LastModifiedById, CreatedDate, LastModifiedDate, SystemModstamp, IsDeleted, Name, Portal_ID__c, External_Id__c, Industry)
  VALUES
    ('001000000000001AAA', '10000000-0000-0000-0000-000000000001', '10000000-0000-0000-0000-000000000001', '10000000-0000-0000-0000-000000000001', NOW(), NOW(), NOW(), 0, 'Acme Contract', 'PORTAL-001', 'EXT-001', 'Technology'),
    ('001000000000002AAA', '10000000-0000-0000-0000-000000000001', '10000000-0000-0000-0000-000000000001', '10000000-0000-0000-0000-000000000001', NOW(), NOW(), NOW(), 0, 'Acme Duplicate', 'PORTAL-002', 'EXT-002', 'Technology');

  REPLACE INTO Contact
    (Id, OwnerId, CreatedById, LastModifiedById, CreatedDate, LastModifiedDate, SystemModstamp, IsDeleted, Name, FirstName, LastName, AccountId)
  VALUES
    ('003000000000001AAA', '10000000-0000-0000-0000-000000000001', '10000000-0000-0000-0000-000000000001', '10000000-0000-0000-0000-000000000001', NOW(), NOW(), NOW(), 0, NULL, 'Ada', 'Smith', '001000000000001AAA');

  REPLACE INTO _System_App
    (Id, Name, Label, Description, Icon, Color, NavigationItems, UtilityItems, AssignedProfiles, IsDefault, CreatedDate, LastModifiedDate)
  VALUES
    (
      '06m000000000001AAA',
      '06m000000000001AAA',
      'Sales',
      'Sales app',
      '/img/icon.svg',
      '#16325c',
      '[{\"id\":\"0DM000000000001\",\"type\":\"object\",\"objectApiName\":\"Account\",\"label\":\"Accounts\",\"icon\":\"/img/icon.svg\"}]',
      '[]',
      '[]',
      1,
      NOW(),
      NOW()
    );

  REPLACE INTO AppMenuItem
    (Id, Label, Description, StartUrl, Type, IsVisible, SortOrder, AppId, Icon, Color, IsDeleted, CreatedDate, LastModifiedDate)
  VALUES
    ('0DC000000000001AAA', 'Sales', 'Sales app', '/lightning/app/06m000000000001AAA', 'App', 1, 0, '06m000000000001AAA', '/img/icon.svg', '#16325c', 0, NOW(), NOW());
"

ensure_list_view "00B000000000001AAA" "Account" "All Accounts" "" '["Id","Name"]'
ensure_list_view "00B000000000002AAA" "Account" "My Accounts" 'OwnerId = CURRENT_USER' '["Id","Name"]'

echo
echo "local standard objects initialized"
echo "if the backend was already running, restart it only if object metadata was newly created and not yet visible"
