// queries/statements_header_pdf.go
package queries

import (
	"bssapp-backend/db"
	"bssapp-backend/models"
	"database/sql"
	"fmt"
	"log"
	"strings"
)

// küçük yardımcı: boşlukları temizle, her değeri ayrı tırnakla sar
func buildQuotedHList(vals []string) string {
	var pp []string
	for _, v := range vals {
		v = strings.TrimSpace(v)
		if v != "" {
			pp = append(pp, fmt.Sprintf("'%s'", v)) // '1','2' gibi
		}
	}
	if len(pp) == 0 {
		return ""
	}
	return strings.Join(pp, ",")
}

/* ============================ HEADER (Ana Tablo) ============================ */

func GetStatementsHPDF(accountCode, startDate, endDate string, parislemler []string) ([]models.StatementHeader, []string, error) {
	// Account normalize
	if len(accountCode) == 7 && strings.ContainsAny(accountCode, "0123456789") {
		accountCode = accountCode[:3] + " " + accountCode[3:]
	}

	// IN list parse et
	inList := buildQuotedHList(parislemler)
	parislemCond := "''"
	if inList != "" {
		parislemCond = inList
	}

	query := fmt.Sprintf(`
;WITH Opening AS (
    SELECT 
        b.CurrAccCode AS Cari_Kod,
        b.DocCurrencyCode AS Para_Birimi,
        SUM(c.Debit - c.Credit) AS Devir_Bakiyesi
    FROM trCurrAccBook b
    LEFT JOIN trCurrAccBookCurrency c
      ON c.CurrAccBookID = b.CurrAccBookID
     AND c.CurrencyCode  = b.DocCurrencyCode
    WHERE b.CurrAccCode LIKE @Carikod
      AND b.DocumentDate < @StartDate
      AND EXISTS (
            SELECT 1
            FROM CurrAccBookATAttributesFilter f2
            WHERE f2.CurrAccBookID = b.CurrAccBookID
              AND f2.ATAtt01 IN (%s)
      )
    GROUP BY b.CurrAccCode, b.DocCurrencyCode
),
Movements AS (
    SELECT 
        b.CurrAccCode        AS Cari_Kod,
        d.CurrAccDescription AS Cari_Isim,
        CONVERT(varchar(10), b.DocumentDate, 23) AS Belge_Tarihi, 
        CONVERT(varchar(10), b.DueDate, 23)      AS Vade_Tarihi, 
        b.RefNumber          AS Belge_No,
        b.BaseApplicationCode AS Islem_Tipi,
        b.LineDescription    AS Aciklama,
        b.DocCurrencyCode    AS Para_Birimi,
        c.Debit              AS Borc,
        c.Credit             AS Alacak,
        SUM(c.Debit - c.Credit)
            OVER (PARTITION BY b.CurrAccCode, c.CurrencyCode 
                  ORDER BY b.DocumentDate, b.CurrAccBookID) AS Hareket_Bakiyesi,
        f.ATAtt01 AS Parislemler
    FROM trCurrAccBook b
    LEFT JOIN cdCurrAccDesc d
        ON b.CurrAccCode = d.CurrAccCode AND d.LangCode = 'TR'
    LEFT JOIN trCurrAccBookCurrency c
        ON b.CurrAccBookID = c.CurrAccBookID
       AND b.DocCurrencyCode = c.CurrencyCode
    LEFT JOIN CurrAccBookATAttributesFilter f
        ON b.CurrAccBookID = f.CurrAccBookID
    WHERE b.CurrAccCode LIKE @Carikod
      AND b.DocumentDate BETWEEN @StartDate AND @EndDate
      AND EXISTS (
            SELECT 1 
            FROM CurrAccBookATAttributesFilter f2
            WHERE f2.CurrAccBookID = b.CurrAccBookID
              AND f2.ATAtt01 IN (%s)
      )
)`, parislemCond, parislemCond)
	query += fmt.Sprintf(`
SELECT 
    m.Cari_Kod,
    m.Cari_Isim,
    m.Belge_Tarihi,
    m.Vade_Tarihi,
    m.Belge_No,
    m.Islem_Tipi,
    m.Aciklama,
    m.Para_Birimi,
    m.Borc,
    m.Alacak,
    ISNULL(o.Devir_Bakiyesi,0) + m.Hareket_Bakiyesi AS Bakiye,
    m.Parislemler
FROM Movements m
LEFT JOIN Opening o
  ON o.Cari_Kod = m.Cari_Kod
 AND o.Para_Birimi = m.Para_Birimi

UNION ALL

-- Devir satırı
SELECT  
    @Carikod                    AS Cari_Kod,
    MAX(d.CurrAccDescription)   AS Cari_Isim,
    CONVERT(varchar(10), @StartDate, 23) AS Belge_Tarihi, 
    CONVERT(varchar(10), @StartDate, 23) AS Vade_Tarihi, 
    'Baslangic_devir'           AS Belge_No,
    'Devir'                     AS Islem_Tipi,
    'Devir Bakiyesi'            AS Aciklama,
    b.DocCurrencyCode           AS Para_Birimi,
    SUM(c.Debit)                AS Borc,
    SUM(c.Credit)               AS Alacak,
    SUM(c.Debit) - SUM(c.Credit) AS Bakiye,
    (
      SELECT STRING_AGG(x.ATAtt01, ',')
      FROM (
        SELECT DISTINCT f2.ATAtt01
        FROM CurrAccBookATAttributesFilter f2
        INNER JOIN trCurrAccBook bb
          ON f2.CurrAccBookID = bb.CurrAccBookID
        WHERE bb.CurrAccCode LIKE @Carikod
          AND bb.DocumentDate < @StartDate
          AND f2.ATAtt01 IN (%s)
      ) x
    ) AS Parislemler
FROM trCurrAccBook b
LEFT JOIN cdCurrAccDesc d
    ON b.CurrAccCode = d.CurrAccCode AND d.LangCode = 'TR'
LEFT JOIN trCurrAccBookCurrency c
    ON b.CurrAccBookID = c.CurrAccBookID
   AND b.DocCurrencyCode = c.CurrencyCode
WHERE b.CurrAccCode LIKE @Carikod
  AND b.DocumentDate < @StartDate
GROUP BY b.DocCurrencyCode

ORDER BY Para_Birimi, Belge_Tarihi;`, parislemCond)

	rows, err := db.MssqlDB.Query(query,
		sql.Named("Carikod", "%"+accountCode+"%"),
		sql.Named("StartDate", startDate),
		sql.Named("EndDate", endDate),
	)
	if err != nil {
		log.Printf("❌ Header sorgu hatası: %v", err)
		return nil, nil, fmt.Errorf("header sorgu hatası: %v", err)
	}
	defer rows.Close()

	var headers []models.StatementHeader
	var belgeNos []string
	for rows.Next() {
		var h models.StatementHeader
		if err := rows.Scan(
			&h.CariKod, &h.CariIsim,
			&h.BelgeTarihi, &h.VadeTarihi,
			&h.BelgeNo, &h.IslemTipi,
			&h.Aciklama, &h.ParaBirimi,
			&h.Borc, &h.Alacak,
			&h.Bakiye, &h.Parislemler,
		); err != nil {
			log.Printf("❌ Header scan hatası: %v", err)
			return nil, nil, err
		}
		headers = append(headers, h)
		if h.BelgeNo != "" {
			belgeNos = append(belgeNos, h.BelgeNo)
		}
	}
	log.Printf("✅ Header verileri alındı: %d kayıt, %d belge no", len(headers), len(belgeNos))
	return headers, belgeNos, nil
}
