package queries

import (
	"bssapp-backend/auth"
	"bssapp-backend/internal/authz"
	"context"
	"database/sql"
	"fmt"
)

// ========================================================
// 📌 GetOrderList — FINAL + CURRENCY SAFE + PIYASA AUTHZ
//
//	✅ TotalAmount artık trOrderLineCurrency(NetAmount) üzerinden
//	   ve CurrencyCode = Header.DocCurrencyCode satırından gelir.
//
// ========================================================
func GetOrderList(
	ctx context.Context,
	mssql *sql.DB,
	pg *sql.DB,
	search string,
) (*sql.Rows, error) {

	claims, ok := auth.GetClaimsFromContext(ctx)
	if !ok || claims == nil {
		return nil, fmt.Errorf("unauthorized: claims not found")
	}

	// ----------------------------------------------------
	// 🔐 PIYASA FILTER (ADMIN BYPASS)
	// ----------------------------------------------------
	piyasaWhere := "1=1"

	if !claims.IsAdmin() {

		codes, err := authz.GetUserPiyasaCodes(pg, int(claims.ID))
		if err != nil {
			return nil, fmt.Errorf("piyasa codes load error: %w", err)
		}

		if len(codes) == 0 {
			piyasaWhere = "1=0"
		} else {
			piyasaWhere = authz.BuildINClause(
				"UPPER(f2.CustomerAtt01)",
				codes,
			)
		}
	}

	// ----------------------------------------------------
	// 📄 BASE QUERY
	// ----------------------------------------------------
	baseQuery := fmt.Sprintf(`
SELECT
    CAST(h.OrderHeaderID AS NVARCHAR(50))           AS OrderHeaderID,
    ISNULL(h.OrderNumber, '')                      AS OrderNumber,
    CONVERT(varchar, h.OrderDate, 23)              AS OrderDate,
    CONVERT(varchar, h.AverageDueDate, 23)         AS TerminTarihi,

    ISNULL(h.CurrAccCode, '')                      AS CurrAccCode,
    ISNULL(ca.CurrAccDescription, '')              AS CurrAccDescription,

    ISNULL(mt.AttributeDescription, '')            AS MusteriTemsilcisi,
    ISNULL(py.AttributeDescription, '')            AS Piyasa,

    CONVERT(varchar, h.CreditableConfirmedDate,23) AS CreditableConfirmedDate,
    ISNULL(h.DocCurrencyCode,'TRY')                AS DocCurrencyCode,

    ISNULL(l.TotalAmount,0)                        AS TotalAmount,

    ----------------------------------------------------------------
    -- USD HESABI (TRY / EUR / GBP / USD DESTEKLİ)
    ----------------------------------------------------------------
    CASE
        WHEN h.DocCurrencyCode = 'USD'
            THEN ISNULL(l.TotalAmount,0)

        WHEN h.DocCurrencyCode = 'TRY'
             AND usd.Rate > 0
            THEN ISNULL(l.TotalAmount,0) / usd.Rate

        WHEN h.DocCurrencyCode IN ('EUR','GBP')
             AND cur.Rate > 0
             AND usd.Rate > 0
            THEN (ISNULL(l.TotalAmount,0) * cur.Rate) / usd.Rate

        ELSE 0
    END                                            AS TotalAmountUSD,

    ISNULL(l.PackedAmount,0)                       AS PackedAmount,

    CASE
        WHEN h.DocCurrencyCode = 'USD'
            THEN ISNULL(l.PackedAmount,0)

        WHEN h.DocCurrencyCode = 'TRY'
             AND usd.Rate > 0
            THEN ISNULL(l.PackedTRY,0) / usd.Rate

        WHEN cur.Rate > 0
             AND usd.Rate > 0
            THEN (ISNULL(l.PackedAmount,0) * cur.Rate) / usd.Rate

        ELSE 0
    END                                            AS PackedUSD,

    CASE
        WHEN ISNULL(l.TotalAmount,0) > 0
            THEN (ISNULL(l.PackedAmount,0) * 100.0) / NULLIF(l.TotalAmount,0)
        ELSE 0
    END                                            AS PackedRatePct,

    ISNULL(h.IsCreditableConfirmed,0)              AS IsCreditableConfirmed,
    CASE
        WHEN EXISTS (
            SELECT 1
            FROM dbo.trOrderLine l2
            WHERE l2.OrderHeaderID = h.OrderHeaderID
              AND ISNULL(l2.ItemCode,'') LIKE 'U%%'
        )
            THEN CAST(1 AS bit)
        ELSE CAST(0 AS bit)
    END                                            AS HasUretimUrunu,
    ISNULL(h.Description,'')                       AS Description,

    usd.Rate                                       AS ExchangeRateUSD

FROM dbo.trOrderHeader h

-- ✅ TOPLAM ARTIK trOrderLineCurrency'den: CurrencyCode = DocCurrencyCode
JOIN (
    SELECT
        l.OrderHeaderID,
        SUM(ISNULL(c.NetAmount,0)) AS TotalAmount,
        SUM(
            CASE
                WHEN ISNULL(c.CurrencyCode,'') = 'TRY'
                    THEN ISNULL(c.NetAmount,0)
                ELSE 0
            END
        ) AS TotalTRY,
        SUM(
            CASE
                -- "Paketlenen" = satir kapaliysa VEYA satir irsaliyeye/faturaya baglandiysa.
                -- Not: IsClosed her zaman guncellenmiyor; trInvoiceLine.OrderLineID iliskiyi yakalar.
                WHEN ISNULL(l.IsClosed,0) = 1
                  OR il.OrderLineID IS NOT NULL
                    THEN ISNULL(c.NetAmount,0)
                ELSE 0
            END
        ) AS PackedAmount,
        SUM(
            CASE
                WHEN (ISNULL(l.IsClosed,0) = 1 OR il.OrderLineID IS NOT NULL)
                AND ISNULL(c.CurrencyCode,'') = 'TRY'
                    THEN ISNULL(c.NetAmount,0)
                ELSE 0
            END
        ) AS PackedTRY
    FROM dbo.trOrderLine l
    JOIN dbo.trOrderHeader h2
      ON h2.OrderHeaderID = l.OrderHeaderID
    LEFT JOIN (
        SELECT DISTINCT OrderLineID
        FROM BAGGI_V3.dbo.trInvoiceLine
        WHERE OrderLineID IS NOT NULL
    ) il
      ON il.OrderLineID = l.OrderLineID
    LEFT JOIN dbo.trOrderLineCurrency c
      ON c.OrderLineID  = l.OrderLineID
     AND c.CurrencyCode = ISNULL(h2.DocCurrencyCode,'TRY')
    GROUP BY l.OrderHeaderID
) l
  ON l.OrderHeaderID = h.OrderHeaderID

LEFT JOIN dbo.cdCurrAccDesc ca
  ON ca.CurrAccCode = h.CurrAccCode
 AND ca.LangCode = 'TR'

-- müşteri temsilcisi + piyasa açıklamaları
LEFT JOIN dbo.CustomerAttributesFilter f
  ON f.CurrAccCode = h.CurrAccCode

LEFT JOIN dbo.cdCurrAccAttributeDesc mt
  ON mt.CurrAccTypeCode    = 3
 AND mt.AttributeTypeCode  = 2
 AND mt.AttributeCode      = f.CustomerAtt02
 AND mt.LangCode           = 'TR'

LEFT JOIN dbo.cdCurrAccAttributeDesc py
  ON py.CurrAccTypeCode    = 3
 AND py.AttributeTypeCode  = 1
 AND py.AttributeCode      = f.CustomerAtt01
 AND py.LangCode           = 'TR'

----------------------------------------------------------------
-- USD → TRY
----------------------------------------------------------------
OUTER APPLY (
    SELECT TOP 1 Rate
    FROM dbo.AllExchangeRates
    WHERE CurrencyCode = 'USD'
      AND RelationCurrencyCode = 'TRY'
      AND ExchangeTypeCode = 6
      AND Rate > 0
      AND Date <= CAST(GETDATE() AS date)
    ORDER BY Date DESC
) usd

----------------------------------------------------------------
-- ORDER PB → TRY
----------------------------------------------------------------
OUTER APPLY (
    SELECT TOP 1 Rate
    FROM dbo.AllExchangeRates
    WHERE CurrencyCode = h.DocCurrencyCode
      AND RelationCurrencyCode = 'TRY'
      AND ExchangeTypeCode = 6
      AND Rate > 0
      AND Date <= CAST(GETDATE() AS date)
    ORDER BY Date DESC
) cur

WHERE
    ISNULL(h.IsCancelOrder,0) = 0
    AND h.OrderTypeCode = 1
    AND h.ProcessCode   = 'WS'
    AND h.IsClosed      = 0

    -- 🔐 PIYASA AUTHZ (EXISTS — SAĞLAM YOL)
    AND EXISTS (
        SELECT 1
        FROM dbo.CustomerAttributesFilter f2
        WHERE f2.CurrAccCode = h.CurrAccCode
          AND %s
    )
`, piyasaWhere)

	// ----------------------------------------------------
	// 🔍 SEARCH FILTER (CASE + TR SAFE)
	// ----------------------------------------------------
	if search != "" {
		baseQuery += `
AND EXISTS (
  SELECT 1
  FROM dbo.trOrderHeader h2
  LEFT JOIN dbo.cdCurrAccDesc ca2
    ON ca2.CurrAccCode = h2.CurrAccCode
   AND ca2.LangCode = 'TR'
  WHERE h2.OrderHeaderID = h.OrderHeaderID
    AND (
      LOWER(REPLACE(REPLACE(h2.OrderNumber,'İ','I'),'ı','i'))
        COLLATE Latin1_General_CI_AI LIKE LOWER(@p1)

      OR LOWER(REPLACE(REPLACE(h2.CurrAccCode,'İ','I'),'ı','i'))
        COLLATE Latin1_General_CI_AI LIKE LOWER(@p1)

      OR LOWER(REPLACE(REPLACE(ca2.CurrAccDescription,'İ','I'),'ı','i'))
        COLLATE Latin1_General_CI_AI LIKE LOWER(@p1)

      OR LOWER(REPLACE(REPLACE(h2.Description,'İ','I'),'ı','i'))
        COLLATE Latin1_General_CI_AI LIKE LOWER(@p1)
    )
)
`
	}

	// ----------------------------------------------------
	// 📌 ORDER
	// ----------------------------------------------------
	baseQuery += `
ORDER BY h.CreatedDate DESC
`

	// ----------------------------------------------------
	// ▶ EXECUTE
	// ----------------------------------------------------
	if search != "" {
		searchLike := fmt.Sprintf("%%%s%%", search)
		return mssql.Query(baseQuery, searchLike)
	}

	return mssql.Query(baseQuery)
}
