package goatcounter

import (
	"context"

	"zgo.at/errors"
	"zgo.at/zdb"
	"zgo.at/zvalidate"
)

type CampaignID int32

type Campaign struct {
	ID     CampaignID `db:"campaign_id" json:"campaign_id"`
	SiteID SiteID     `db:"site_id" json:"site_id"`
	Name   string     `db:"name" json:"name"`
}

func (c *Campaign) Defaults(ctx context.Context) {}

func (c *Campaign) Validate() error {
	v := zvalidate.New()
	v.Required("name", c.Name)
	return v.ErrorOrNil()
}

func (c *Campaign) Insert(ctx context.Context) error {
	if c.ID > 0 {
		return errors.Errorf("Campaign.Insert: c.ID>0: %d", c.ID)
	}

	c.Defaults(ctx)
	err := c.Validate()
	if err != nil {
		return errors.Wrap(err, "Campaign.Insert")
	}

	c.ID, err = zdb.InsertID[CampaignID](ctx, "campaign_id",
		`insert into campaigns (site_id, name) values (?, ?)`, MustGetSite(ctx).ID, c.Name)
	if err != nil {
		return errors.Wrap(err, "Campaign.Insert")
	}
	return nil
}

func (c *Campaign) ByName(ctx context.Context, name string) error {
	k := c.Name
	if cc, ok := cacheCampaigns(ctx).Get(k); ok {
		*c = *cc
		return nil
	}

	err := zdb.Get(ctx, c, `select * from campaigns where site_id=? and lower(name)=lower(?)`,
		MustGetSite(ctx).ID, name)
	if err != nil {
		return errors.Wrap(err, "Campaign.ByName")
	}

	cacheCampaigns(ctx).Set(k, c)
	return nil
}
