package invoice

import (
	"fmt"
	"strings"
	"time"

	"gitlab.com/pactual1/backend/models"
	"gitlab.com/pactual1/backend/shared"
)

func GetInvoices(buyerName string, sortBy string, limit int, offset int, ids []int64, status []string) ([]models.Invoice, int64, error) {
	var invoices []models.Invoice

	// Default sort by InvoiceDate DESC
	sortField := "invoice_date"
	sortOrder := "desc"

	if sortBy == "InvoiceDate" || sortBy == "InvoiceDueDate" {
		sortField = strings.ToLower(sortBy)
	}

	dbOrder := fmt.Sprintf("%s %s", sortField, sortOrder)

	db := shared.GetDb()
	countDb := db

	if buyerName != "" {
		db = db.Where("buyer_name LIKE ?", "%"+buyerName+"%")
		countDb = countDb.Where("buyer_name LIKE ?", "%"+buyerName+"%")
	}

	// Added conditional for ID search
	if len(ids) > 0 {
		db = db.Where("id in (?)", ids)
		countDb = countDb.Where("id in (?)", ids)
	}

    // Added conditional for status search
	if len(status) > 0 {
		db = db.Where("status in (?)", status)
		countDb = countDb.Where("status in (?)", status)
	}

	var total int64
	if err := countDb.Model(&models.Invoice{}).Count(&total).Error; err != nil {
		return nil, 0, err
	}

	if err := db.Preload("InvoiceItem").
		Order(dbOrder).
		Limit(limit).
		Offset(offset).
		Find(&invoices).Error; err != nil {
		return nil, 0, err
	}

	for i := range invoices {
		var sum int64
		if invoices[i].InvoiceItem != nil {
			for _, item := range invoices[i].InvoiceItem {
				sum += item.PriceCents * item.Quantity
			}
			invoices[i].PriceCents = sum
		}
	}

	return invoices, total, nil
}

func CountInvoicesByMultipleStatuses(companyID uint, startTime, endTime time.Time) (int64, int64, map[string]map[string]int64, error) {
    var claimed, issued int64
    monthlyCounts := make(map[string]map[string]int64)

    // Iterate through each month within the specified date range
    for dt := startTime; dt.Before(endTime); dt = dt.AddDate(0, 1, 0) {
        monthEnd := dt.AddDate(0, 1, 0)
        if monthEnd.After(endTime) {
            monthEnd = endTime
        }

        // Initialize monthlyCounts for the current month
        monthKey := dt.Format("2006-01")
        monthlyCounts[monthKey] = map[string]int64{"insurance_claimed": 0, "invoice_issued": 0}

        // Query for 'insurance_claimed' invoices for the current month
        var monthlyClaimed int64
        err := shared.GetDb().Model(&models.Invoice{}).
            Where("status = ? AND (buyer_id = ? OR seller_id = ?) AND invoice_date >= ? AND invoice_due_date <= ?", "insurance_claimed", companyID, companyID, dt, monthEnd).
            Count(&monthlyClaimed).Error
        if err != nil {
            return 0, 0, nil, err
        }

        // Query for 'invoice_issued' invoices for the current month
        var monthlyIssued int64
        err = shared.GetDb().Model(&models.Invoice{}).
            Where("status = ? AND (buyer_id = ? OR seller_id = ?) AND invoice_date >= ? AND invoice_due_date <= ?", "invoice_issued", companyID, companyID, dt, monthEnd).
            Count(&monthlyIssued).Error
        if err != nil {
            return 0, 0, nil, err
        }

        // Update the counts for the current month
        monthlyCounts[monthKey]["insurance_claimed"] = monthlyClaimed
        monthlyCounts[monthKey]["invoice_issued"] = monthlyIssued

        // Update the total counts
        claimed += monthlyClaimed
        issued += monthlyIssued
    }

    return claimed, issued, monthlyCounts, nil
}
