package db

import (
	"context"

	"github.com/jackc/pgx/v5/pgtype"
)

// ListSalesActivities lists sales-activities with optional filters. Hand-written
// (sqlc cannot regenerate in this environment); mirrors the generated
// ListSalesVisits pattern and scans into db.ListSalesActivitiesRow.
const listSalesActivities = `-- name: ListSalesActivities :many
SELECT sa.id, sa.sales_id, sa.sales_visit_id, sa.activity_date, sa.activity_type,
       sa.description, sa.result, sa.follow_up_date, sa.follow_up_notes, sa.created_at, sa.updated_at,
       COALESCE(e.name, '') AS sales_name,
       COALESCE(c.name, '') AS customer_name,
       to_char(sa.created_at, 'HH24:MI') AS activity_time,
       COALESCE(sa.description, '') AS notes
FROM sales_activities sa
LEFT JOIN employees e ON e.id = sa.sales_id
LEFT JOIN sales_visits sv ON sv.id = sa.sales_visit_id
LEFT JOIN customers c ON c.id = sv.customer_id
WHERE ($1::bigint IS NULL OR sa.sales_id = $1)
  AND ($2::text IS NULL OR sa.activity_type = $2)
  AND ($3::date IS NULL OR sa.activity_date >= $3)
  AND ($4::date IS NULL OR sa.activity_date <= $4)
ORDER BY sa.activity_date DESC, sa.created_at DESC
LIMIT $5 OFFSET $6
`

type ListSalesActivitiesRow struct {
	ID            int64              `json:"id"`
	SalesID       pgtype.Int8        `json:"sales_id"`
	SalesVisitID  pgtype.Int8        `json:"sales_visit_id"`
	ActivityDate  pgtype.Date        `json:"activity_date"`
	ActivityType  string             `json:"activity_type"`
	Description   pgtype.Text        `json:"description"`
	Result        pgtype.Text        `json:"result"`
	FollowUpDate  pgtype.Date        `json:"follow_up_date"`
	FollowUpNotes pgtype.Text        `json:"follow_up_notes"`
	CreatedAt     pgtype.Timestamptz `json:"created_at"`
	UpdatedAt     pgtype.Timestamptz `json:"updated_at"`
	SalesName     string             `json:"sales_name"`
	CustomerName  string             `json:"customer_name"`
	Time          string             `json:"time"`
	Notes         string             `json:"notes"`
}

type ListSalesActivitiesParams struct {
	SalesID      pgtype.Int8 `json:"sales_id"`
	ActivityType string      `json:"activity_type"`
	DateFrom     pgtype.Date `json:"date_from"`
	DateTo       pgtype.Date `json:"date_to"`
	Limit        int32       `json:"limit"`
	Offset       int32       `json:"offset"`
}

func (q *Queries) ListSalesActivities(ctx context.Context, arg ListSalesActivitiesParams) ([]ListSalesActivitiesRow, error) {
	rows, err := q.db.Query(ctx, listSalesActivities,
		arg.SalesID, arg.ActivityType, arg.DateFrom, arg.DateTo, arg.Limit, arg.Offset)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []ListSalesActivitiesRow{}
	for rows.Next() {
		var i ListSalesActivitiesRow
		if err := rows.Scan(
			&i.ID,
			&i.SalesID,
			&i.SalesVisitID,
			&i.ActivityDate,
			&i.ActivityType,
			&i.Description,
			&i.Result,
			&i.FollowUpDate,
			&i.FollowUpNotes,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.SalesName,
			&i.CustomerName,
			&i.Time,
			&i.Notes,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const countSalesActivities = `-- name: CountSalesActivities :one
SELECT count(*) FROM sales_activities
WHERE ($1::bigint IS NULL OR sales_id = $1)
  AND ($2::text IS NULL OR activity_type = $2)
  AND ($3::date IS NULL OR activity_date >= $3)
  AND ($4::date IS NULL OR activity_date <= $4)
`

type CountSalesActivitiesParams struct {
	SalesID      pgtype.Int8 `json:"sales_id"`
	ActivityType string      `json:"activity_type"`
	DateFrom     pgtype.Date `json:"date_from"`
	DateTo       pgtype.Date `json:"date_to"`
}

func (q *Queries) CountSalesActivities(ctx context.Context, arg CountSalesActivitiesParams) (int64, error) {
	row := q.db.QueryRow(ctx, countSalesActivities, arg.SalesID, arg.ActivityType, arg.DateFrom, arg.DateTo)
	var count int64
	err := row.Scan(&count)
	return count, err
}
