#!/bin/bash
set -euo pipefail

# =====================================================
# NS20 AI Image (Still JPG) Growth Report Generator
# - Independent from ns20_1_ai_report.sh (LLM-only)
# - Uses same openai_connect.inc and same MySQL table
#   (ns20_1_ai_report) but stores json_file with image_ prefix
# =====================================================

BASE_DIR="$(cd "$(dirname "$0")" && pwd)"
REPORT_DIR="$BASE_DIR/reports"
RAW_DIR="$BASE_DIR/raw"
IMAGE_REPORT_DIR="$REPORT_DIR/image_reports"
mkdir -p "$REPORT_DIR" "$RAW_DIR" "$IMAGE_REPORT_DIR"

source "$BASE_DIR/openai_connect.inc"

# -----------------------------------------------------
# Args
#   1) deviceid (required)
#   2) image_path (optional) - if omitted, auto-pick latest image for today
# -----------------------------------------------------
DEVICEID="${1:-}"
IMAGE_PATH="${2:-}"

if [ -z "$DEVICEID" ]; then
  echo "[ERROR] deviceid argument is required"
  echo "Usage: $0 <deviceid> [image_path]"
  exit 1
fi

if [ -z "${FARM_NAME[$DEVICEID]+x}" ]; then
  echo "[ERROR] Unknown deviceid: $DEVICEID"
  exit 1
fi

FARM="${FARM_NAME[$DEVICEID]}"
CROP="${CROP_TYPE[$DEVICEID]}"

# -----------------------------------------------------
# Resolve camera name and locate image if not provided
# -----------------------------------------------------
get_cam_name() {
  local did="$1"
  if [ -n "${CAM_NAME[$did]+x}" ] && [ -n "${CAM_NAME[$did]}" ]; then
    echo "${CAM_NAME[$did]}"
    return
  fi
  # Default: deviceid 끝자리 숫자 -> camN
  local suffix="${did##*_}"           # e.g., 003
  local last="${suffix: -1}"          # e.g., 3
  if [[ "$last" =~ ^[0-9]$ ]]; then
    echo "cam${last}"
  else
    echo "cam1"
  fi
}

CAM="$(get_cam_name "$DEVICEID")"

pick_latest_image() {
  local cam="$1"
  local today_dir
  today_dir="$(date +"%Y%m%d")"
  local base="$CAM_ROOT/$cam/$today_dir/images"
  if [ -d "$base" ]; then
    # pick newest by mtime
    local latest
    latest="$(ls -1t "$base"/*.jpg 2>/dev/null | head -n 1 || true)"
    if [ -n "$latest" ]; then
      echo "$latest"
      return
    fi
  fi

  # fallback: search last 7 days
  local latest_any
  latest_any="$(find "$CAM_ROOT/$cam" -maxdepth 4 -type f \( -iname "*.jpg" -o -iname "*.jpeg" \) -printf "%T@ %p\n" 2>/dev/null | sort -nr | head -n 1 | awk '{print $2}' || true)"
  if [ -n "$latest_any" ]; then
    echo "$latest_any"
    return
  fi

  echo ""
}

if [ -z "$IMAGE_PATH" ]; then
  IMAGE_PATH="$(pick_latest_image "$CAM")"
fi

if [ -z "$IMAGE_PATH" ] || [ ! -f "$IMAGE_PATH" ]; then
  echo "[ERROR] Image file not found. deviceid=$DEVICEID cam=$CAM image_path=$IMAGE_PATH"
  exit 1
fi

# -----------------------------------------------------
# Parse capture time from filename: PYYMMDDHHMMSS??.jpg
# example: P26012708595910.jpg -> 2026-01-27 08:59:59
# -----------------------------------------------------
BASENAME="$(basename "$IMAGE_PATH")"

CAPTURE_TS=""
CAPTURE_ISO=""

if [[ "$BASENAME" =~ ^P([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})[0-9]{2}\.(jpg|jpeg|JPG|JPEG)$ ]]; then
  YY="${BASH_REMATCH[1]}"
  MM="${BASH_REMATCH[2]}"
  DD="${BASH_REMATCH[3]}"
  hh="${BASH_REMATCH[4]}"
  mi="${BASH_REMATCH[5]}"
  ss="${BASH_REMATCH[6]}"
  YYYY="20${YY}"
  CAPTURE_TS="${YYYY}${MM}${DD}_${hh}${mi}${ss}"
  CAPTURE_ISO="${YYYY}-${MM}-${DD} ${hh}:${mi}:${ss}"
else
  # fallback: filesystem mtime
  CAPTURE_TS="$(date -r "$IMAGE_PATH" +"%Y%m%d_%H%M%S")"
  CAPTURE_ISO="$(date -r "$IMAGE_PATH" +"%Y-%m-%d %H:%M:%S")"
fi

REPORT_DATE="${CAPTURE_ISO:0:10}"

OUT_FILE="image_${DEVICEID}_${CAPTURE_TS}.json"
RAW_FILE="$RAW_DIR/openai_image_raw_${DEVICEID}_${CAPTURE_TS}.json"
OUT_REL="image_reports/$OUT_FILE"
OUT_PATH="$IMAGE_REPORT_DIR/$OUT_FILE"

echo "[INFO] DeviceID    : $DEVICEID"
echo "[INFO] Farm        : $FARM"
echo "[INFO] Crop        : $CROP"
echo "[INFO] Camera      : $CAM"
echo "[INFO] Image       : $IMAGE_PATH"
echo "[INFO] CaptureTime : $CAPTURE_ISO"
echo "[INFO] ReportOut   : $OUT_PATH"

# -----------------------------------------------------
# Fetch nearest environment row around capture time
# ns20_1.datetime is VARCHAR, so attempt multiple parse formats.
# -----------------------------------------------------
SQL_FMT1="
SELECT datetime,temp,humidity,co2,cds,gtemp,ver,lat,lng,alt
FROM ns20_1
WHERE deviceid='$DEVICEID'
ORDER BY ABS(TIMESTAMPDIFF(SECOND, STR_TO_DATE(datetime,'%Y-%m-%d %H:%i:%s'), STR_TO_DATE('$CAPTURE_ISO','%Y-%m-%d %H:%i:%s')))
LIMIT 1;
"

ROW="$(mysql -u"$MYSQL_USER" -p"$MYSQL_PASS" -h"$MYSQL_HOST" "$MYSQL_DB" -N -e "$SQL_FMT1" 2>/dev/null || true)"

if [ -z "$ROW" ]; then
  SQL_FMT2="
  SELECT datetime,temp,humidity,co2,cds,gtemp,ver,lat,lng,alt
  FROM ns20_1
  WHERE deviceid='$DEVICEID'
  ORDER BY ABS(TIMESTAMPDIFF(SECOND, STR_TO_DATE(datetime,'%Y%m%d%H%i%s'), STR_TO_DATE('${CAPTURE_ISO//[-: ]/}','%Y%m%d%H%i%s')))
  LIMIT 1;
  "
  ROW="$(mysql -u"$MYSQL_USER" -p"$MYSQL_PASS" -h"$MYSQL_HOST" "$MYSQL_DB" -N -e "$SQL_FMT2" 2>/dev/null || true)"
fi

# split tab-separated row
DB_DATETIME=""
TEMP=""
HUMI=""
CO2=""
CDS=""
GTEMP=""
VER=""
LAT=""
LNG=""
ALT=""

if [ -n "$ROW" ]; then
  IFS=$'\t' read -r DB_DATETIME TEMP HUMI CO2 CDS GTEMP VER LAT LNG ALT <<< "$ROW"
fi

# -----------------------------------------------------
# Build prompt + OpenAI Vision request
# -----------------------------------------------------
IMG_B64="$(base64 -w 0 "$IMAGE_PATH")"
IMG_DATA_URL="data:image/jpeg;base64,$IMG_B64"

PROMPT=$(cat <<EOF
너는 스마트팜 작물 생육/이상징후 분석 전문가 AI다.

[농장명] $FARM
[작목] $CROP
[촬영시각] $CAPTURE_ISO
[센서시각(가장 근접)] ${DB_DATETIME:-"N/A"}
[온도] ${TEMP:-"N/A"} °C
[습도] ${HUMI:-"N/A"} %
[CO2] ${CO2:-"N/A"}
[조도(CDS)] ${CDS:-"N/A"}
[GPS] lat=${LAT:-"N/A"}, lng=${LNG:-"N/A"}, alt=${ALT:-"N/A"}

아래 항목을 이미지(정지 JPG) 기반으로 추정/판단하라.
단, 확신이 낮으면 "주의" 또는 "불량" 대신 "주의"로 두고, reason에 근거와 불확실성을 명확히 적어라.

반드시 JSON만 출력하라 (설명문 금지).

{
  "overall_growth": "양호 | 주의 | 불량",
  "leaf_color": {
    "status": "정상 | 황화 | 갈변 | 반점 | 기타",
    "detail": "관찰 요약"
  },
  "wilting_stress": {
    "status": "없음 | 의심 | 있음",
    "signs": ["징후1","징후2"]
  },
  "env_relation": {
    "risk_level": "낮음 | 보통 | 높음",
    "analysis": "온도/습도와 이미지 관찰의 연관성 해석",
    "recommended_actions": ["조치1","조치2","조치3"]
  },
  "confidence": 0.0,
  "reason": "판단 근거 (짧고 명확)"
}
EOF
)

MAX_RETRY=3
RETRY=1
SUCCESS=0

while [ $RETRY -le $MAX_RETRY ]; do
  echo "[INFO] OpenAI request attempt $RETRY/$MAX_RETRY"

  REQUEST_JSON=$(jq -n \
    --arg model "$OPENAI_MODEL" \
    --arg system "You are an agricultural vision analyst. Return only valid JSON." \
    --arg text "$PROMPT" \
    --arg img "$IMG_DATA_URL" \
    '{
      model: $model,
      messages: [
        {role: "system", content: $system},
        {role: "user", content: [
          {type: "text", text: $text},
          {type: "image_url", image_url: {url: $img}}
        ]}
      ],
      temperature: 0.2
    }'
  )

  curl -s https://api.openai.com/v1/chat/completions \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $OPENAI_API_KEY" \
    -d "$REQUEST_JSON" \
    > "$RAW_FILE"

  if jq -e '.error' "$RAW_FILE" >/dev/null 2>&1; then
    echo "[WARN] OpenAI API error:"
    jq '.error.message' "$RAW_FILE"
  else
    # Extract JSON content (string -> JSON)
    CONTENT="$(jq -r '.choices[0].message.content' "$RAW_FILE" 2>/dev/null || true)"
    if [ -n "$CONTENT" ]; then
      echo "$CONTENT" | jq '.' > "$OUT_PATH" 2>/dev/null || true
    fi

    if [ -s "$OUT_PATH" ]; then
      SUCCESS=1
      break
    fi
  fi

  sleep 2
  RETRY=$((RETRY + 1))
done

if [ $SUCCESS -ne 1 ]; then
  echo "[ERROR] OpenAI failed after $MAX_RETRY attempts"
  exit 1
fi

# -----------------------------------------------------
# Save metadata JSON wrapper (enrich) -> overwrite OUT_PATH with merged object
# -----------------------------------------------------
TMP_JSON="$(mktemp)"
jq -n \
  --arg deviceid "$DEVICEID" \
  --arg farm_name "$FARM" \
  --arg crop_type "$CROP" \
  --arg camera "$CAM" \
  --arg image_path "$IMAGE_PATH" \
  --arg capture_time "$CAPTURE_ISO" \
  --arg sensor_time "${DB_DATETIME:-}" \
  --arg temp "${TEMP:-}" \
  --arg humidity "${HUMI:-}" \
  --arg co2 "${CO2:-}" \
  --arg cds "${CDS:-}" \
  --arg gtemp "${GTEMP:-}" \
  --arg ver "${VER:-}" \
  --arg lat "${LAT:-}" \
  --arg lng "${LNG:-}" \
  --arg alt "${ALT:-}" \
  --slurpfile analysis "$OUT_PATH" \
  '{
    deviceid: $deviceid,
    farm_name: $farm_name,
    crop_type: $crop_type,
    camera: $camera,
    image_path: $image_path,
    capture_time: $capture_time,
    sensor: {
      datetime: ($sensor_time | if .=="" then null else . end),
      temp: ($temp | if .=="" then null else (tonumber? // .) end),
      humidity: ($humidity | if .=="" then null else (tonumber? // .) end),
      co2: ($co2 | if .=="" then null else (tonumber? // .) end),
      cds: ($cds | if .=="" then null else (tonumber? // .) end),
      gtemp: ($gtemp | if .=="" then null else (tonumber? // .) end),
      ver: ($ver | if .=="" then null else . end),
      gps: {
        lat: ($lat | if .=="" then null else (tonumber? // .) end),
        lng: ($lng | if .=="" then null else (tonumber? // .) end),
        alt: ($alt | if .=="" then null else (tonumber? // .) end)
      }
    },
    analysis: ($analysis[0] // {})
  }' > "$TMP_JSON"

mv "$TMP_JSON" "$OUT_PATH"

# -----------------------------------------------------
# Insert into existing MySQL table (NO schema changes)
# report_date uses capture date; json_file stores relative path under reports/
# -----------------------------------------------------
mysql -u"$MYSQL_USER" -p"$MYSQL_PASS" -h"$MYSQL_HOST" "$MYSQL_DB" -e "
INSERT INTO ns20_1_ai_report
(deviceid, farm_name, crop_type, report_date, json_file)
VALUES
('$DEVICEID', '$FARM', '$CROP', '$REPORT_DATE', '$OUT_REL');
"

echo "[DONE] AI image report generated successfully: $OUT_REL"
