#!/usr/bin/env bash
set -euo pipefail

# Script Name: clip
# Description: Smart clipboard manager with history, search, and categories
# Usage: clip              # Show history with fzf search
#        clip pin          # Pin current clipboard item
#        clip cat 5        # Show 5th history item
#        clip search "192" # Search history
#        clip clear        # Clear history

VERSION="1.0.0"
CLIP_DIR="$HOME/.clipboard"
HISTORY_FILE="$CLIP_DIR/history.txt"
PINS_FILE="$CLIP_DIR/pins.txt"
MAX_HISTORY=100

# Colors
readonly GREEN='\033[0;32m'
readonly YELLOW='\033[1;33m'
readonly BLUE='\033[0;34m'
readonly RED='\033[0;31m'
readonly CYAN='\033[0;36m'
readonly MAGENTA='\033[0;35m'
readonly BOLD='\033[1m'
readonly NC='\033[0m'

# Initialize clip directory
init_clip() {
  if [[ ! -d "$CLIP_DIR" ]]; then
    mkdir -p "$CLIP_DIR"
    touch "$HISTORY_FILE"
    touch "$PINS_FILE"
  fi
}

show_help() {
  echo -e "${BOLD}clip${NC} - Smart Clipboard Manager v${VERSION}"
  echo
  echo -e "${BOLD}USAGE:${NC}"
  echo "  clip [COMMAND]"
  echo
  echo -e "${BOLD}COMMANDS:${NC}"
  echo -e "  ${CYAN}(no args)${NC}       Show history with fzf search"
  echo -e "  ${CYAN}pin${NC}             Pin current clipboard item"
  echo -e "  ${CYAN}pins${NC}            Show pinned items"
  echo -e "  ${CYAN}cat N${NC}           Show Nth history item"
  echo -e "  ${CYAN}search TERM${NC}     Search history"
  echo -e "  ${CYAN}list${NC}            List recent history (last 20)"
  echo -e "  ${CYAN}save${NC}            Save current clipboard to history"
  echo -e "  ${CYAN}clear${NC}           Clear history"
  echo -e "  ${CYAN}delete N${NC}        Delete Nth history item"
  echo -e "  ${CYAN}unpin N${NC}         Delete Nth pinned item"
  echo -e "  ${CYAN}stats${NC}           Show statistics"
  echo -e "  ${CYAN}-h, --help${NC}      Show this help"
  echo
  echo -e "${BOLD}EXAMPLES:${NC}"
  echo "  clip                  # Interactive search"
  echo "  clip pin              # Pin important item"
  echo "  clip search \"192.168\" # Find IP addresses"
  echo "  clip cat 1            # Show most recent"
  echo "  clip delete 5         # Delete 5th item from history"
  echo "  clip unpin 1          # Delete 1st pinned item"
  echo
  echo -e "${BOLD}FEATURES:${NC}"
  echo "  - Automatic history (monitors clipboard)"
  echo "  - Pattern detection (URLs, IPs, hashes)"
  echo "  - Security: Auto-expire sensitive data"
  echo "  - Pin important items"
  echo "  - fzf integration for search"
  echo
  echo -e "${BOLD}NOTES:${NC}"
  echo "  History: $HISTORY_FILE"
  echo "  Pins: $PINS_FILE"
  echo "  Max history: $MAX_HISTORY items"
}

# Detect content type
detect_type() {
  local content="$1"

  # URL
  if [[ "$content" =~ ^https?:// ]]; then
    echo "url"
  # IPv4
  elif [[ "$content" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} ]]; then
    echo "ip"
  # Hash (32 or 40 or 64 hex chars)
  elif [[ "$content" =~ ^[a-f0-9]{32}$ ]] || [[ "$content" =~ ^[a-f0-9]{40}$ ]] || [[ "$content" =~ ^[a-f0-9]{64}$ ]]; then
    echo "hash"
  # Code (contains common code markers)
  elif [[ "$content" =~ (function|const|var|class|def|import|export) ]]; then
    echo "code"
  # Credential patterns (don't save these!)
  elif [[ "$content" =~ (password|secret|token|key|bearer|api[_-]?key) ]]; then
    echo "credential"
  else
    echo "text"
  fi
}

# Save item to history
save_to_history() {
  local content="$1"
  local type=$(detect_type "$content")

  # Don't save credentials
  if [[ "$type" == "credential" ]]; then
    echo -e "${YELLOW}⚠${NC} Sensitive data detected - not saved to history" >&2
    return 0
  fi

  # Don't save empty
  if [[ -z "$content" ]]; then
    return 0
  fi

  # Don't save if it's already the most recent
  if [[ -f "$HISTORY_FILE" ]]; then
    last_entry=$(tail -1 "$HISTORY_FILE" | cut -d'|' -f3-)
    if [[ "$last_entry" == "$content" ]]; then
      return 0
    fi
  fi

  # Save: timestamp|type|content
  timestamp=$(date '+%Y-%m-%d %H:%M:%S')
  echo "$timestamp|$type|$content" >> "$HISTORY_FILE"

  # Trim history to max size
  if [[ $(wc -l < "$HISTORY_FILE") -gt $MAX_HISTORY ]]; then
    tail -n $MAX_HISTORY "$HISTORY_FILE" > "$HISTORY_FILE.tmp"
    mv "$HISTORY_FILE.tmp" "$HISTORY_FILE"
  fi
}

# Get current clipboard
get_clipboard() {
  if command -v xsel &>/dev/null; then
    xsel --output --clipboard
  elif command -v xclip &>/dev/null; then
    xclip -selection clipboard -o
  else
    echo "Error: No clipboard tool found" >&2
    return 1
  fi
}

# Set clipboard
set_clipboard() {
  if command -v xsel &>/dev/null; then
    echo -n "$1" | xsel --input --clipboard
  elif command -v xclip &>/dev/null; then
    echo -n "$1" | xclip -selection clipboard
  else
    echo "Error: No clipboard tool found" >&2
    return 1
  fi
}

# Interactive history browser with fzf
show_history_fzf() {
  if ! command -v fzf &>/dev/null; then
    echo -e "${RED}Error:${NC} fzf not found" >&2
    echo "Install it with: sudo apt install fzf" >&2
    exit 1
  fi

  if [[ ! -f "$HISTORY_FILE" ]] || [[ ! -s "$HISTORY_FILE" ]]; then
    echo -e "${YELLOW}No history yet${NC}" >&2
    exit 0
  fi

  # Format for fzf: index | time | type | preview
  selected=$(tac "$HISTORY_FILE" | awk -F'|' '
    {
      idx = NR
      time = $1
      type = $2
      content = $3
      for (i=4; i<=NF; i++) content = content "|" $i

      # Truncate preview
      preview = content
      if (length(preview) > 60) {
        preview = substr(preview, 1, 60) "..."
      }

      printf "%3d | %s | %-10s | %s\n", idx, time, "[" type "]", preview
    }
  ' | fzf --height=60% --layout=reverse \
    --header="Select item to copy (ESC to cancel)" \
    --preview='echo {}' \
    --preview-window=up:3:wrap)

  if [[ -n "$selected" ]]; then
    # Extract the full content
    index=$(echo "$selected" | awk '{print $1}')
    full_content=$(tac "$HISTORY_FILE" | sed -n "${index}p" | cut -d'|' -f3-)

    # Copy to clipboard
    set_clipboard "$full_content"
    echo -e "${GREEN}✓${NC} Copied to clipboard"
  fi
}

# Pin current clipboard
pin_item() {
  local content=$(get_clipboard)

  if [[ -z "$content" ]]; then
    echo -e "${RED}Error:${NC} Clipboard is empty" >&2
    exit 1
  fi

  type=$(detect_type "$content")
  timestamp=$(date '+%Y-%m-%d %H:%M:%S')

  echo "$timestamp|$type|$content" >> "$PINS_FILE"
  echo -e "${GREEN}✓${NC} Pinned item (type: $type)"
}

# Show pins
show_pins() {
  if [[ ! -f "$PINS_FILE" ]] || [[ ! -s "$PINS_FILE" ]]; then
    echo -e "${YELLOW}No pinned items${NC}"
    exit 0
  fi

  echo -e "${BOLD}${CYAN}Pinned Items:${NC}"
  echo

  if command -v fzf &>/dev/null; then
    # Interactive selection
    selected=$(cat "$PINS_FILE" | awk -F'|' '
      {
        idx = NR
        time = $1
        type = $2
        content = $3
        for (i=4; i<=NF; i++) content = content "|" $i

        preview = content
        if (length(preview) > 60) {
          preview = substr(preview, 1, 60) "..."
        }

        printf "%3d | %s | %-10s | %s\n", idx, time, "[" type "]", preview
      }
    ' | fzf --height=60% --layout=reverse \
      --header="Select pinned item to copy (ESC to cancel)" \
      --preview='echo {}')

    if [[ -n "$selected" ]]; then
      index=$(echo "$selected" | awk '{print $1}')
      full_content=$(sed -n "${index}p" "$PINS_FILE" | cut -d'|' -f3-)
      set_clipboard "$full_content"
      echo -e "${GREEN}✓${NC} Copied pinned item to clipboard"
    fi
  else
    # Just list them
    cat "$PINS_FILE" | awk -F'|' '
      {
        idx = NR
        time = $1
        type = $2
        content = $3
        for (i=4; i<=NF; i++) content = content "|" $i

        preview = content
        if (length(preview) > 60) {
          preview = substr(preview, 1, 60) "..."
        }

        printf "%3d | %s | %-10s | %s\n", idx, time, "[" type "]", preview
      }
    '
  fi
}

# Show specific item
show_item() {
  local index=$1

  if [[ ! -f "$HISTORY_FILE" ]]; then
    echo -e "${RED}Error:${NC} No history" >&2
    exit 1
  fi

  content=$(tac "$HISTORY_FILE" | sed -n "${index}p" | cut -d'|' -f3-)

  if [[ -z "$content" ]]; then
    echo -e "${RED}Error:${NC} No item at index $index" >&2
    exit 1
  fi

  echo "$content"
}

# Search history
search_history() {
  local query="$1"

  if [[ ! -f "$HISTORY_FILE" ]]; then
    echo -e "${RED}Error:${NC} No history" >&2
    exit 1
  fi

  echo -e "${BOLD}${CYAN}Search results for: ${query}${NC}"
  echo

  grep -i "$query" "$HISTORY_FILE" | awk -F'|' '
    {
      time = $1
      type = $2
      content = $3
      for (i=4; i<=NF; i++) content = content "|" $i

      preview = content
      if (length(preview) > 60) {
        preview = substr(preview, 1, 60) "..."
      }

      printf "%s | %-10s | %s\n", time, "[" type "]", preview
    }
  '
}

# List recent items
list_recent() {
  if [[ ! -f "$HISTORY_FILE" ]]; then
    echo -e "${YELLOW}No history${NC}"
    exit 0
  fi

  echo -e "${BOLD}${CYAN}Recent Clipboard History (last 20):${NC}"
  echo

  tail -20 "$HISTORY_FILE" | tac | awk -F'|' '
    {
      idx = NR
      time = $1
      type = $2
      content = $3
      for (i=4; i<=NF; i++) content = content "|" $i

      preview = content
      if (length(preview) > 60) {
        preview = substr(preview, 1, 60) "..."
      }

      printf "%3d | %s | %-10s | %s\n", idx, time, "[" type "]", preview
    }
  '
}

# Statistics
show_stats() {
  if [[ ! -f "$HISTORY_FILE" ]]; then
    echo -e "${YELLOW}No history${NC}"
    exit 0
  fi

  total=$(wc -l < "$HISTORY_FILE")
  pins=$(wc -l < "$PINS_FILE" 2>/dev/null || echo 0)

  echo -e "${BOLD}${CYAN}Clipboard Statistics:${NC}"
  echo
  echo "  Total items: $total"
  echo "  Pinned items: $pins"
  echo "  Max history: $MAX_HISTORY"
  echo

  echo -e "${BOLD}${CYAN}By Type:${NC}"
  awk -F'|' '{print $2}' "$HISTORY_FILE" | sort | uniq -c | sort -rn | awk '
    {printf "  %-15s %d\n", $2, $1}'
}

# Delete specific item from history
delete_item() {
  local index=$1

  if [[ ! -f "$HISTORY_FILE" ]]; then
    echo -e "${RED}Error:${NC} No history" >&2
    exit 1
  fi

  total=$(wc -l < "$HISTORY_FILE")
  if [[ $index -lt 1 ]] || [[ $index -gt $total ]]; then
    echo -e "${RED}Error:${NC} Invalid index (1-$total)" >&2
    exit 1
  fi

  # Show what we're deleting
  content=$(tac "$HISTORY_FILE" | sed -n "${index}p" | cut -d'|' -f3-)
  preview="${content:0:60}"
  if [[ ${#content} -gt 60 ]]; then
    preview="${preview}..."
  fi

  echo -e "${YELLOW}Delete item $index:${NC} $preview"
  echo -n "Continue? (y/N) "
  read -r response

  if [[ "$response" =~ ^[Yy]$ ]]; then
    # Delete line (remember tac reverses order)
    actual_line=$((total - index + 1))
    sed -i "${actual_line}d" "$HISTORY_FILE"
    echo -e "${GREEN}✓${NC} Deleted item $index"
  else
    echo "Cancelled"
  fi
}

# Delete pinned item
delete_pin() {
  local index=$1

  if [[ ! -f "$PINS_FILE" ]] || [[ ! -s "$PINS_FILE" ]]; then
    echo -e "${YELLOW}No pinned items${NC}"
    exit 0
  fi

  total=$(wc -l < "$PINS_FILE")
  if [[ $index -lt 1 ]] || [[ $index -gt $total ]]; then
    echo -e "${RED}Error:${NC} Invalid index (1-$total)" >&2
    exit 1
  fi

  # Show what we're deleting
  content=$(sed -n "${index}p" "$PINS_FILE" | cut -d'|' -f3-)
  preview="${content:0:60}"
  if [[ ${#content} -gt 60 ]]; then
    preview="${preview}..."
  fi

  echo -e "${YELLOW}Unpin item $index:${NC} $preview"
  echo -n "Continue? (y/N) "
  read -r response

  if [[ "$response" =~ ^[Yy]$ ]]; then
    sed -i "${index}d" "$PINS_FILE"
    echo -e "${GREEN}✓${NC} Unpinned item $index"
  else
    echo "Cancelled"
  fi
}

# Clear history
clear_history() {
  echo -n "Clear clipboard history? (y/N) "
  read -r response
  if [[ "$response" =~ ^[Yy]$ ]]; then
    > "$HISTORY_FILE"
    echo -e "${GREEN}✓${NC} History cleared"
  else
    echo "Cancelled"
  fi
}

# Initialize
init_clip

# Parse command
if [[ $# -eq 0 ]]; then
  show_history_fzf
  exit 0
fi

case $1 in
  -h|--help|help)
    show_help
    ;;
  save)
    content=$(get_clipboard)
    save_to_history "$content"
    echo -e "${GREEN}✓${NC} Saved to history"
    ;;
  pin)
    pin_item
    ;;
  pins)
    show_pins
    ;;
  cat)
    if [[ $# -lt 2 ]]; then
      echo -e "${RED}Error:${NC} Item index required" >&2
      exit 1
    fi
    show_item "$2"
    ;;
  search|s)
    if [[ $# -lt 2 ]]; then
      echo -e "${RED}Error:${NC} Search query required" >&2
      exit 1
    fi
    shift
    search_history "$*"
    ;;
  list|ls|l)
    list_recent
    ;;
  delete|del|rm)
    if [[ $# -lt 2 ]]; then
      echo -e "${RED}Error:${NC} Item index required" >&2
      exit 1
    fi
    delete_item "$2"
    ;;
  unpin)
    if [[ $# -lt 2 ]]; then
      echo -e "${RED}Error:${NC} Item index required" >&2
      exit 1
    fi
    delete_pin "$2"
    ;;
  clear)
    clear_history
    ;;
  stats)
    show_stats
    ;;
  *)
    echo -e "${RED}Error:${NC} Unknown command: $1" >&2
    echo "Run 'clip --help' for usage" >&2
    exit 1
    ;;
esac
