set -eo pipefail

# Colour codes
GREEN='\033[0;32m'
LIGHT_GREEN='\033[1;32m'
RED='\033[0;31m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
MAGENTA='\033[0;35m'
YELLOW='\033[1;33m'
WHITE='\033[1;37m'
BOLD='\033[1m'
NC='\033[0m' # No Colour

# Configuration
MAX_SUBJECT_LENGTH=50
TYPES=(feat fix docs style refactor test chore perf ci build)

print_fancy_header() {
    local title="$1"
    local width=60
    local line=$(printf '%*s' "$width" | tr ' ' '─')

    printf "${BLUE}┌${line}┐${NC}\n"
    printf "${BLUE}│ ${CYAN}%-$((width-2))s ${BLUE}│${NC}\n" "$title"
    printf "${BLUE}└${line}┘${NC}\n"
}

auto_correct_commit_message() {
    local commit_file="$1"
    local commit_msg
    local corrected=false

    if [ ! -f "$commit_file" ]; then
        printf "${RED}Warning: Commit message file not found. Skipping validation.${NC}\n"
        return 0
    fi

    commit_msg=$(sed -e '/^#/d' -e '/^\s*$/d' "$commit_file" | head -n1)

    if [ -z "$commit_msg" ]; then
        printf "${RED}Warning: Commit message is empty. Please provide a meaningful commit message.${NC}\n"
        print_commit_message_guide
        return 1
    fi

    local type=$(echo "$commit_msg" | cut -d':' -f1 | tr '[:upper:]' '[:lower:]')
    local subject=$(echo "$commit_msg" | cut -d':' -f2- | xargs)

    # Auto-correct type
    if ! echo "${TYPES[@]}" | grep -qw "$type"; then
        local closest_type=$(echo "${TYPES[@]}" | tr ' ' '\n' | sort -u | grep -i "^$type" | head -n1)
        if [ -n "$closest_type" ]; then
            type=$closest_type
            corrected=true
            printf "${YELLOW}Auto-corrected type to '${type}'.${NC}\n"
        else
            printf "${RED}Error: Invalid commit type '%s'. Unable to auto-correct.${NC}\n" "$type"
            print_commit_message_guide
            return 1
        fi
    fi

    # Auto-correct subject capitalization
    if [[ ! $subject =~ ^[A-Z] ]]; then
        subject="$(tr '[:lower:]' '[:upper:]' <<< ${subject:0:1})${subject:1}"
        corrected=true
        printf "${YELLOW}Auto-capitalized the subject line.${NC}\n"
    fi

    # Remove trailing period if present
    if [[ $subject =~ \.$  ]]; then
        subject="${subject%.}"
        corrected=true
        printf "${YELLOW}Removed trailing period from the subject line.${NC}\n"
    fi

    # Truncate subject if too long
    if [ ${#subject} -gt $MAX_SUBJECT_LENGTH ]; then
        subject="${subject:0:$MAX_SUBJECT_LENGTH}"
        corrected=true
        printf "${YELLOW}Truncated subject to ${MAX_SUBJECT_LENGTH} characters.${NC}\n"
    fi

    # Update commit message file if corrections were made
    if [ "$corrected" = true ]; then
        echo "${type}: ${subject}" > "$commit_file"
        printf "${GREEN}Commit message has been auto-corrected.${NC}\n"
    else
        printf "${GREEN}Commit message is valid. No corrections needed.${NC}\n"
    fi

    return 0
}

print_commit_message_guide() {
    printf "\n${BOLD}${BLUE}Commit Message Guide:${NC}\n"
    printf "  ${CYAN}• ${BOLD}Format:${NC} <type>: <subject>\n"
    printf "  ${CYAN}• ${BOLD}Allowed Types:${NC} ${LIGHT_GREEN}%s${NC}\n" "${TYPES[*]}"
    printf "  ${CYAN}• ${BOLD}Rules:${NC}\n"
    printf "    - Keep the subject line under %d characters\n" $MAX_SUBJECT_LENGTH
    printf "    - Use the imperative mood in the subject line\n"
    printf "    - Capitalize the subject line\n"
    printf "    - Do not end the subject line with a period\n"
    printf "\n  ${MAGENTA}${BOLD}Examples of valid commit messages:${NC}\n"
    printf "  ${GREEN}✓${NC} ${CYAN}feat: Add new user registration feature${NC}\n"
    printf "  ${GREEN}✓${NC} ${CYAN}fix: Resolve login issue with Google OAuth${NC}\n"
    printf "  ${GREEN}✓${NC} ${CYAN}docs: Update README with new API endpoints${NC}\n"
    printf "  ${GREEN}✓${NC} ${CYAN}style: Format code according to new style guide${NC}\n"
    printf "  ${GREEN}✓${NC} ${CYAN}refactor: Simplify data processing pipeline${NC}\n"
    printf "  ${GREEN}✓${NC} ${CYAN}test: Add unit tests for user service${NC}\n"
    printf "  ${GREEN}✓${NC} ${CYAN}chore: Update dependencies to latest versions${NC}\n"
}

main() {
    print_fancy_header "Commit Message Validation and Auto-correction"
    printf "\n"

    if auto_correct_commit_message "$1"; then
        printf "\n${GREEN}✨ ${BOLD}Commit message is now valid. Proceeding with commit. ✨${NC}\n"
    else
        printf "\n${RED}Unable to auto-correct commit message. Please review and try again.${NC}\n"
        exit 1
    fi
}

# Run the main function, but catch any errors
if ! main "$@"; then
    printf "${RED}Commit message validation and auto-correction failed. Please review and try again.${NC}\n"
    exit 1
fi
