package mdb

import (
	"context"
	_ "embed"

	"zombiezen.com/go/sqlite/sqlitex"

	"git.sunturtle.xyz/zephyr/horse"
)

var (
	//go:embed sql/support.sql
	supportSQL string
	//go:embed sql/support-effect.sql
	supportEffectSQL string
	//go:embed sql/support-hint.sql
	supportHintSQL string
)

func SupportCards(ctx context.Context, db *sqlitex.Pool) ([]horse.SupportCard, error) {
	// We don't use load here because we have multiple queries to run.
	conn, err := db.Take(ctx)
	defer db.Put(conn)
	if err != nil {
		return nil, err
	}
	var sc []horse.SupportCard
	{
		stmt := conn.Prep(supportSQL)
		defer stmt.Reset()
		for {
			ok, err := stmt.Step()
			if err != nil {
				return nil, err
			}
			if !ok {
				break
			}
			s := horse.SupportCard{
				ID:          horse.SupportCardID(stmt.ColumnInt(0)),
				Name:        stmt.ColumnText(1),
				CharacterID: horse.CharacterID(stmt.ColumnInt(2)),
				CharaName:   stmt.ColumnText(3),
				Rarity:      horse.SupportCardRarity(stmt.ColumnInt(4)),
				Specialty:   horse.SupportCardSpecialty(stmt.ColumnInt(6)),
				Type:        horse.SupportCardType(stmt.ColumnInt(7)),
				Outings:     stmt.ColumnInt32(9),
			}
			if u := stmt.ColumnText(10); u != "" {
				s.UniqueEffect = &horse.UniqueEffect{
					Name:      u,
					Desc:      stmt.ColumnText(11),
					CardLevel: stmt.ColumnInt32(12),
					Type:      horse.SupportCardEffectType(stmt.ColumnInt(13)),
					Args: trimZeros(
						stmt.ColumnInt32(14),
						stmt.ColumnInt32(15),
						stmt.ColumnInt32(16),
						stmt.ColumnInt32(17),
						stmt.ColumnInt32(18),
					),
					Type2: horse.SupportCardEffectType(stmt.ColumnInt(19)),
					Args2: trimZeros(
						stmt.ColumnInt32(20),
						stmt.ColumnInt32(21),
						stmt.ColumnInt32(22),
						stmt.ColumnInt32(23),
						stmt.ColumnInt32(24),
					),
					IdleSubRate: stmt.ColumnInt32(25),
				}
			}
			sc = append(sc, s)
		}
	}
	{
		stmt := conn.Prep(supportEffectSQL)
		defer stmt.Reset()
		cur := sc
		for {
			ok, err := stmt.Step()
			if err != nil {
				return nil, err
			}
			if !ok {
				break
			}
			id := stmt.ColumnInt(0)
			for len(cur) > 0 && cur[0].ID != horse.SupportCardID(id) {
				cur = cur[1:]
			}
			if len(cur) == 0 {
				break
			}
			typ := horse.SupportCardEffectType(stmt.ColumnInt(1))
			for i := range cur[0].Effects {
				cur[0].Effects[i] = append(cur[0].Effects[i], horse.SupportCardEffect{
					Type:  typ,
					Value: stmt.ColumnInt32(2 + i),
				})
			}
		}
	}
	{
		stmt := conn.Prep(supportHintSQL)
		defer stmt.Reset()
		cur := sc
		last := 0
		for {
			ok, err := stmt.Step()
			if err != nil {
				return nil, err
			}
			if !ok {
				break
			}
			id := stmt.ColumnInt(0)
			for len(cur) > 0 && cur[0].ID != horse.SupportCardID(id) {
				cur = cur[1:]
				last = 0
			}
			group := stmt.ColumnInt(1)
			if group != last {
				cur[0].Hints = append(cur[0].Hints, horse.Hint{})
				last = group
			}
			hint := &cur[0].Hints[len(cur[0].Hints)-1]
			if stmt.ColumnInt(2) == 0 {
				hint.SkillID = horse.SkillID(stmt.ColumnInt(3))
			} else {
				switch stmt.ColumnInt(3) {
				case 1:
					hint.Speed = int8(stmt.ColumnInt(4))
				case 2:
					hint.Stamina = int8(stmt.ColumnInt(4))
				case 3:
					hint.Power = int8(stmt.ColumnInt(4))
				case 4:
					hint.Guts = int8(stmt.ColumnInt(4))
				case 5:
					hint.Wit = int8(stmt.ColumnInt(4))
				case 30:
					hint.SP = int8(stmt.ColumnInt(4))
				default:
					panic("horse: unknown support card hint stat")
				}
			}
		}
	}
	return sc, nil
}
