namespace :reports do

	desc "Debtors List"
	task :debtors_list, [:end_date, :project] do |t, args|
		end_date = args[:end_date] || Date.today - 1.day # Provide a default if not passed
    	project = args[:project] || Project.first.id
    	# @project = Project.find(project)
    	puts("******** #{project} #{end_date}")
	end

	task :payments_performance => :environment do
	  headers = [
	    "#",
	    "Account",
	    "Property No.",
	    "Account Name",
	    "Original Loan",
	    "Tenure"
	  ]

	  CustomerAccount.where(deleted: false).first&.tap do |account|
	    (1..((account.number_of_years.to_i * 12.0) / 3).ceil).each do |q|
	      headers += [
	        "Q#{q} Expected",
	        "Q#{q} Payments",
	        "Q#{q} ExpAmount",
	        "Q#{q} Paid"
	      ]
	    end
	  end

	  headers << "Overall Performance %"

	  puts headers.join(",")

	  x = 0

	  CustomerAccount.where(deleted: false).find_each do |account|
	    row = [
	      x += 1,
	      account.account_number,
	      account.property_number,
	      account.account_name,
	      account.stand_value,
	      account.number_of_years
	    ]

	    total_expected_amount = 0
	    total_paid_amount = 0

	    start_date = account.contract_start_date.beginning_of_day
	    payment_end_date = account.contract_end_date

	    quarter_start = start_date

	    while quarter_start < payment_end_date
	      quarter_end = [quarter_start + 3.months, payment_end_date].min

	      expected = account.customer_account_invoices.where(
	        debit: true,
	        due_date: quarter_start...quarter_end
	      )

	      actual = account.customer_account_invoices.where(
	        debit: false,
	        transaction_date: quarter_start...quarter_end
	      )

	      expected_amount = expected.sum(:amount_due).round(2)
	      paid_amount = actual.sum(:amount).round(2)

	      total_expected_amount += expected_amount
	      total_paid_amount += paid_amount

	      row += [
	        expected.count,
	        actual.count,
	        expected_amount,
	        paid_amount
	      ]

	      quarter_start = quarter_end
	    end

	    performance =
	      if total_expected_amount.to_f > 0
	        ((total_paid_amount.to_f / total_expected_amount.to_f) * 100).round(2)
	      else
	        0
	      end

	    row << performance

	    puts row.join(",")
	  end
	end

	task payments_performance_summary: :environment do
	  require "csv"
	  require "fileutils"

	  output_dir = Rails.root.join("tmp", "reports")
	  FileUtils.mkdir_p(output_dir)

	  file_name = output_dir.join("payments_performance_summary_#{Date.today}.csv")

	  headers = [
	    "#",
	    "Account",
	    "Property No.",
	    "Size",
	    "Account Name",
	    "Description",
	    "Purchase Date",
	    "Purchase Price",
	    "Tenure (Years)",
	    "Expected Revenue",
	    "Actual Revenue",
	    "Months Taken",
	    "Contract End Date",
	    "Last Paid Date",
	    "Payments Performance %",
	    "Completion Performance %",
	    "Payment Status",
	    "Account Status"
	  ]

	  CSV.open(file_name, "w", write_headers: true, headers: headers) do |csv|
	    x = 0

	    CustomerAccount.where(deleted: false).where.not(sale_type_id: 3).find_each do |account|

	      start_date = account.registration_date.to_date
	      today = Date.today
	      stand = account.stand
	      purchase_price = stand.sale_value

	      total_paid_amount = account.customer_account_invoices
	                                 .where(deleted: false, debit: false)
	                                 .sum(:amount)
	      # check if the amount has a takeon balance
		  total_paid_amount += if account.is_takeon?
		                       stand&.amount_paid.to_f + stand&.deposit_paid.to_f
		                     else
		                       0
		                     end
	      
			last_paid_date = account.customer_account_invoices
			                        .where(deleted: false, debit: false)
			                        .order(transaction_date: :desc)
			                        .pick(:transaction_date)

			last_paid_date ||= account.contract_end_date if account.status == "PAIDUP"

			today = last_paid_date if total_paid_amount >= purchase_price.to_f && last_paid_date.present?
		  puts("*** #{today}")
	      months_taken = (today.year - start_date.year) * 12 +
	                     (today.month - start_date.month)

	      months_taken -= 1 if today.day < start_date.day

	      months_taken = 0 if months_taken.negative?

	      expected_months = account.number_of_years.to_i

	      # monthly_instalment =
	      #   if expected_months.positive?
	      #     purchase_price.to_f / expected_months
	      #   else
	      #     0
	      #   end

	      # total_expected_amount = monthly_instalment * months_taken

	      # total_expected_amount = [
	      #   total_expected_amount,
	      #   purchase_price
	      # ].min

	      total_expected_amount = purchase_price

	      payment_performance =
	        if total_expected_amount.positive?
	          ((total_paid_amount / total_expected_amount) * 100).round(2)
	        else
	          0
	        end

	      	if account.status == "PAIDUP"
		      completion_performance =
		        if expected_months.positive?
		          ((months_taken.to_f / expected_months) * 100).round(2)
		        else
		          0
		        end
		    else
		    	completion_performance = "-"
		    end

	        description = "Normal Account"
	        description = "Takeon Account" if account.is_takeon
	        puts("#{account.property_number},#{purchase_price},#{total_paid_amount}")

	      csv << [
	        x += 1,
	        account.account_number,
	        account.property_number,
	        account.stand&.size,
	        account.account_name,
	        description,
	        account.registration_date,
	        purchase_price,
	        account.number_of_years,
	        total_expected_amount.round(2),
	        total_paid_amount.round(2),
	        months_taken,
	        account&.contract_end_date,
	        last_paid_date,
	        payment_performance,
	        completion_performance,
	        account&.last_debtor&.payment_status,
	        account.status
	      ]
	    end
	  end

	  puts "Report saved to #{file_name}"
	end

end