#!/bin/bash
# Project CLI for Gantt Board (API passthrough)
# Usage: ./project.sh [create|list|get|update|delete] [options]

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=./lib/api_client.sh
source "$SCRIPT_DIR/lib/api_client.sh"

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

log_info() { echo -e "${BLUE}i${NC} $1"; }
log_success() { echo -e "${GREEN}ok${NC} $1"; }
log_warning() { echo -e "${YELLOW}warn${NC} $1"; }
log_error() { echo -e "${RED}error${NC} $1"; }

UUID_PATTERN='^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$'

check_dependencies() {
  if ! command -v jq >/dev/null 2>&1; then
    log_error "jq is required. Install with: brew install jq"
    exit 1
  fi
}

show_usage() {
  cat << 'USAGE'
Project CLI for Gantt Board

USAGE:
  ./project.sh [COMMAND] [OPTIONS]

COMMANDS:
  create              Create a new project
  list                List all projects
  get <id-or-name>    Get a specific project
  update <id-or-name> Update a project
  delete <id-or-name> Delete a project

CREATE OPTIONS:
  --name "Name"               Project name (required)
  --description "Description" Project description
  --color "#hexcolor"         Project color

LIST OPTIONS:
  --json                        Output as JSON

UPDATE OPTIONS:
  --name "Name"
  --description "Description"
  --color "#hexcolor"
USAGE
}

resolve_project_id() {
  local identifier="$1"

  if [[ "$identifier" =~ $UUID_PATTERN ]]; then
    echo "$identifier"
    return 0
  fi

  local response
  response=$(api_call GET "/projects")

  local project_id
  project_id=$(echo "$response" | jq -r --arg q "$identifier" '
    .projects
    | map(select((.name // "") | ascii_downcase | contains($q | ascii_downcase)))
    | .[0].id // empty
  ')

  if [[ -n "$project_id" ]]; then
    echo "$project_id"
    return 0
  fi

  log_error "Project '$identifier' not found"
  return 1
}

cmd_create() {
  local name=""
  local description=""
  local color="#3b82f6"

  while [[ $# -gt 0 ]]; do
    case "${1:-}" in
      --name) name="${2:-}"; shift 2 ;;
      --description) description="${2:-}"; shift 2 ;;
      --color) color="${2:-}"; shift 2 ;;
      *) shift ;;
    esac
  done

  if [[ -z "$name" ]]; then
    log_error "Name is required (use --name)"
    exit 1
  fi

  local payload
  payload=$(jq -n --arg name "$name" --arg description "$description" --arg color "$color" '
    {
      name: $name,
      description: (if $description == "" then null else $description end),
      color: $color
    }
  ')

  log_info "Creating project..."
  api_call POST "/projects" "$payload" | jq .
}

cmd_list() {
  local output_json=false

  while [[ $# -gt 0 ]]; do
    case "${1:-}" in
      --json) output_json=true; shift ;;
      *) shift ;;
    esac
  done

  local response
  response=$(api_call GET "/projects")

  if [[ "$output_json" == true ]]; then
    echo "$response" | jq '.projects'
    return
  fi

  local projects
  projects=$(echo "$response" | jq '.projects')
  local count
  count=$(echo "$projects" | jq 'length')
  log_success "Found $count project(s)"

  printf "%-36s %-25s %-30s\n" "ID" "NAME" "DESCRIPTION"
  printf "%-36s %-25s %-30s\n" "------------------------------------" "-------------------------" "------------------------------"

  echo "$projects" | jq -r '.[] | [.id, (.name // "" | tostring | .[0:23]), (.description // "" | tostring | .[0:28])] | @tsv' \
    | while IFS=$'\t' read -r id name desc; do
        printf "%-36s %-25s %-30s\n" "$id" "$name" "$desc"
      done
}

cmd_get() {
  local identifier="${1:-}"
  if [[ -z "$identifier" ]]; then
    log_error "Project ID or name required"
    exit 1
  fi

  local project_id
  project_id=$(resolve_project_id "$identifier")

  log_info "Fetching project $project_id..."
  api_call GET "/projects/$project_id" | jq '.project'
}

cmd_update() {
  local identifier="${1:-}"
  shift || true

  if [[ -z "$identifier" ]]; then
    log_error "Project ID or name required"
    exit 1
  fi

  local project_id
  project_id=$(resolve_project_id "$identifier")

  local updates='{}'
  while [[ $# -gt 0 ]]; do
    case "${1:-}" in
      --name) updates=$(echo "$updates" | jq --arg v "${2:-}" '. + {name: $v}'); shift 2 ;;
      --description) updates=$(echo "$updates" | jq --arg v "${2:-}" '. + {description: $v}'); shift 2 ;;
      --color) updates=$(echo "$updates" | jq --arg v "${2:-}" '. + {color: $v}'); shift 2 ;;
      *) shift ;;
    esac
  done

  if [[ "$updates" == "{}" ]]; then
    log_warning "No update fields specified"
    exit 0
  fi

  local payload
  payload=$(echo "$updates" | jq --arg id "$project_id" '. + {id: $id}')

  log_info "Updating project $project_id..."
  api_call PATCH "/projects" "$payload" | jq .
}

cmd_delete() {
  local identifier="${1:-}"
  if [[ -z "$identifier" ]]; then
    log_error "Project ID or name required"
    exit 1
  fi

  local project_id
  project_id=$(resolve_project_id "$identifier")

  log_info "Deleting project $project_id..."
  api_call DELETE "/projects" "{\"id\": \"$project_id\"}" | jq .
}

check_dependencies

COMMAND="${1:-}"
shift || true

case "$COMMAND" in
  create) cmd_create "$@" ;;
  list) cmd_list "$@" ;;
  get) cmd_get "$@" ;;
  update) cmd_update "$@" ;;
  delete) cmd_delete "$@" ;;
  help|--help|-h|"") show_usage ;;
  *)
    log_error "Unknown command: $COMMAND"
    show_usage
    exit 1
    ;;
esac
