---
- name: Provision WireGuard VPN for new client
  hosts: vpn_servers
  become: yes
  vars:
    client_dir: /etc/wireguard/clients
    wg_interface: wg0
    server_dir: /etc/wireguard
    server_ip: 10.8.0.1/24
    server_port: 51820
    server_endpoint: "{{ ansible_host | default(inventory_hostname) }}"
    
  tasks:
    - name: Debug invoice ID
      debug:
        msg: "Processing invoice ID: {{ invoice_id }}"
        
    # Server Setup Tasks
    - name: Check if server keys exist
      stat:
        path: "{{ server_dir }}/{{ wg_interface }}.conf"
      register: server_config
        
    - name: Generate server private key if not exists
      shell: wg genkey
      register: server_private_key
      when: not server_config.stat.exists
      
    - name: Save server private key
      copy:
        content: "{{ server_private_key.stdout }}"
        dest: "{{ server_dir }}/private.key"
        mode: '0600'
      when: not server_config.stat.exists
      
    - name: Generate server public key
      shell: "cat {{ server_dir }}/private.key | wg pubkey"
      register: server_public_key
      when: not server_config.stat.exists
      
    - name: Save server public key
      copy:
        content: "{{ server_public_key.stdout }}"
        dest: "{{ server_dir }}/public.key"
        mode: '0644'
      when: not server_config.stat.exists
      
    - name: Create initial server config
      template:
        src: templates/server.conf.j2
        dest: "{{ server_dir }}/{{ wg_interface }}.conf"
        mode: '0600'
      when: not server_config.stat.exists
      
    # Client Setup Tasks
    - name: Ensure client directory exists
      file:
        path: "{{ client_dir }}/{{ invoice_id }}"
        state: directory
        mode: '0700'
        
    - name: Generate client private key
      shell: wg genkey
      register: client_private_key
      no_log: true
      
    - name: Save client private key
      copy:
        content: "{{ client_private_key.stdout }}"
        dest: "{{ client_dir }}/{{ invoice_id }}/private.key"
        mode: '0600'
      no_log: true
      
    - name: Generate client public key
      shell: "echo '{{ client_private_key.stdout }}' | wg pubkey"
      register: client_public_key
      
    - name: Save client public key
      copy:
        content: "{{ client_public_key.stdout }}"
        dest: "{{ client_dir }}/{{ invoice_id }}/public.key"
        mode: '0644'
        
    - name: Read server public key
      shell: "cat {{ server_dir }}/public.key"
      register: server_public_key_read
      changed_when: false
        
    - name: Get next available IP
      shell: |
        last_ip=$(grep -h '^Address' {{ client_dir }}/*/wg0.conf 2>/dev/null | tail -n1 | grep -oE '[0-9]+$' || echo 1)
        echo $((last_ip + 1))
      register: next_ip
      
    - name: Generate client config
      template:
        src: templates/client.conf.j2
        dest: "{{ client_dir }}/{{ invoice_id }}/wg0.conf"
        mode: '0600'
      vars:
        client_ip: "10.8.0.{{ next_ip.stdout }}"
        server_pubkey: "{{ server_public_key_read.stdout }}"
        
    - name: Add client to server config
      blockinfile:
        path: "{{ server_dir }}/{{ wg_interface }}.conf"
        marker: "# {mark} ANSIBLE MANAGED BLOCK FOR {{ invoice_id }}"
        block: |
          [Peer]
          PublicKey = {{ client_public_key.stdout }}
          AllowedIPs = 10.8.0.{{ next_ip.stdout }}/32
      notify: restart wireguard
        
  handlers:
    - name: restart wireguard
      service:
        name: wg-quick@{{ wg_interface }}
        state: restarted