package service

import (
	"Portifolio/internal/database"
	"Portifolio/internal/model"
	"database/sql"
	"fmt"
	"time"

	_ "github.com/mattn/go-sqlite3"
)

func InsertRevenue(db *sql.DB, companyID, currencyID int, categoryName string, parentID *int, value float64, period model.Period) error {

	period, err := database.GetPeriodByID(db, period.ID)
	if err != nil {
		err = period.Insert(db)
		if err != nil {
			return err
		}
	}
	// Getting Category, if error, trying to insert the category with the company.
	category, err := database.GetCategoryByName(db, companyID, categoryName)
	if err != nil {
		category = model.RevenueCategory{
			CompanyID: companyID,
			ParentID:  parentID,
			Name:      categoryName,
		}
		err := category.Insert(db)
		if err != nil {
			return err
		}
	}

	_, err = db.Exec(
		`INSERT INTO revenue_entries (company_id, currency_id, category_id, period_id, value)
         VALUES (?, ?, ?, ?, ?)`,
		companyID, currencyID, category.ID, period.ID, value,
	)
	if err != nil {
		return fmt.Errorf("insert revenue_entries: %w", err)
	}

	return nil
}

func GetRevenue(db *sql.DB, companyID int, periodType model.PeriodType, year, idx int) ([]model.Revenue, error) {
	rows, err := db.Query(`
		WITH RECURSIVE tree AS (
			SELECT id, name, parent_id
			FROM category
			WHERE company_id = ? AND parent_id IS NULL

			UNION ALL

			SELECT c.id, c.name, c.parent_id
			FROM category c
			JOIN tree t ON c.parent_id = t.id
		)
		SELECT e.id, t.name, e.value,
		       p.type, p.year, p.idx, p.start_date, p.end_date
		FROM revenue_entries e
		JOIN tree t    ON e.category_id = t.id
		JOIN periods p ON e.period_id   = p.id
		WHERE e.company_id = ? AND p.type = ? AND p.year = ? AND p.idx = ?`,
		companyID, companyID, string(periodType), year, idx,
	)
	if err != nil {
		return nil, fmt.Errorf("query revenue: %w", err)
	}
	defer rows.Close()

	var entries []model.Revenue
	for rows.Next() {
		var e model.Revenue
		var p model.Period
		var start, end string
		if err := rows.Scan(&e.ID, &e.Category, &e.Value,
			&p.Type, &p.Year, &p.Index, &start, &end); err != nil {
			return nil, fmt.Errorf("scan revenue row: %w", err)
		}
		p.Start, _ = time.Parse("2006-01-02", start)
		p.End, _ = time.Parse("2006-01-02", end)
		e.Period = &p
		entries = append(entries, e)
	}
	return entries, rows.Err()
}
