require 'ecaytrade/ad'
require 'ecaytrade/website'
require 'tempfile'
require 'mechanize'

module Ecaytrade
  class Account
    include Net
    attr_reader :cookie,
      :username,
      :ads,
      :agent

    class AdError < ArgumentError; end
    class LoginError < StandardError; end

    # Sync account w/ website
    # Returns:
    #   - self
    def sync
      login unless logged_in?
      url = '/my_items.php'
      reg_items = %r{<form method="POST" action="my_items\.php">.*?<a href="detail\.php\?id=(?<id>\d+)">.*?</form>}m
      reg_more = %r{<a href="(.*?)" class="button">Next 20 &gt;</a>}

      @ads = []
      begin
        @agent.get(url)
        @agent.page.body.scan(reg_items) do |m|
          id = Regexp.last_match[:id]
          @ads << Website.get_ad(id.to_i)
        end
      end while(@agent.page.body.match(reg_more))
      return self
    end

    # Login to ecaytrade
    #
    # Args:
    #   - +username+ -> User's email address
    #   - +password+ -> User's password
    # Returns:
    #   - Account
    def login(password)
      @password = password

      # Try and login
      @agent.get('http://www.ecaytrade.com')
      @agent.page.link_with(text: /Log in/).click
      @agent.page.form_with(action: 'member_login.php') do |f|
        f.username = @username
        f.password = @password
      end.click_button

      link = @agent.page.link_with(text: /click here/i)
      link.click if link

      # Not logged in
      raise LoginError, 'Bad username/password' unless logged_in?()
      sync()
      return self
    end

    # Logout from website
    #
    # Returns:
    #   - self
    def logout
      @agent.page.link_with(text: 'Log out').click if logged_in?
      return self
    end

    # Are we logged in
    #
    # Returns:
    #   - true for yes, false for no
    def logged_in?
      return @agent.page.link_with(text: 'Log out') != nil
    end

    # Add an ad to the account
    #
    # Args:
    #   - +ad+ -> Ad to upload
    # Returns:
    #   - Updated ad object
    def add(ad, images=nil)
      login unless logged_in?
      params = {
        'ad_id' => '',
        'update_rq' => '',
        'catid' => ad.category_id,
        'ad_title' => ad.title,
        'ad_description' => ad.description,
        'submit' => 'Register'
      }
      @agent.post('/item.php', params)
      if @agent.page.body =~ %r{/upload_file\.php\?pic_ad_id=(\d+)'>}
        ad.id = $~[1].to_i
      else
        raise IOError, "Failed to upload ad [#{ad.id}]"
      end

      # Upload images to newly created image
      images.each_index do |i|
        add_image(ad.id, ad.images[i], images[i])
      end

      return Ecaytrade::Website.get_ad(ad.id);
    end

    # Remove ad from account
    #
    # Args:
    #   - +ad+ -> Ad to remove
    # Returns:
    #   - +ad+ -> Ad removed
    def remove(ad)
      login unless logged_in?
      @agent.get("/my_items.php?deleteid=#{ad.id}&confirmed=1")
      ad.id = nil
      return ad
    end

    # Mark ad as sold
    #
    # Args:
    #   - +ad+ -> Ad object
    # Returns:
    #   - ad
    def sold(ad)
      login unless logged_in?
      @agent.get("/my_items.php?soldid=#{ad.id}")
      ad = Ecaytrade::Website.get_ad(ad.id)
      return ad
    end

    # Ad an image to an an
    #
    # Args:
    #   - +ad_id+ -> Target ad's id
    #   - +image_path+ -> File path to image
    # Returns:
    #   - Ad's id
    def add_image(ad_id, image_path, data = nil)
      login unless logged_in?
      if (data)
        file = Tempfile.new(Filename.basename(image_path));
      else
        file = File.new(image_path)
      end
      @agent.get('/upload_file.php', {pic_ad_id: ad_id})
      @agent.page.form_with(action: '/upload_file.php') do |f|
        puts f.inspect
        f.file_uploads.first.file_name = image_path
        puts f.inspect
      end.click_button
      return ad_id
    end

    # Create account object and login
    #
    # Args:
    #   - +username+ -> email address associated with account
    #   - +password+ -> password for account
    # Returns:
    #   - Account object in the logged in state
    def self.login(username, password)
      account = Account.new(username)
      account.login(password)
      return account
    end

    private
    def initialize(username)
      @username = username
      @agent = Mechanize.new { |agent|
        # Flickr refreshes after login
        agent.user_agent_alias = 'Mac Safari'
        agent.follow_meta_refresh = true
      }
    end
  end
end
