package controller

import (
	"context"
	"fmt"
	"strconv"
	"ticket-pimp/internal/domain"
	"ticket-pimp/internal/storage/db"

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

func (wc *WorkflowController) Get(ctx context.Context) (*domain.ApplicationConfig, error) {
	c, err := wc.q.GetConfig(ctx)
	return &domain.ApplicationConfig{
		Key: c.TicketKey.String,
		ID:  int(c.TicketID.Int32),
	}, err
}

func (wc *WorkflowController) NewKey(ctx context.Context) (*domain.ApplicationConfig, error) {
	c, err := wc.q.SetNewConfig(ctx)
	return &domain.ApplicationConfig{
		Key: c.TicketKey.String,
		ID:  int(c.TicketID.Int32),
	}, err
}

func (wc *WorkflowController) ProjectCreate(ctx context.Context, project domain.Project) (*domain.Project, error) {

	tx, err := wc.pool.Begin(ctx)
	if err != nil {
		return nil, err
	}
	defer tx.Rollback(ctx)

	qtx := wc.q.WithTx(tx)

	appconfig, err := qtx.SetNewConfig(ctx)
	if err != nil {
		return nil, err
	}

	project.Key = fmt.Sprintf(
		"%s-%d",
		appconfig.TicketKey.String,
		appconfig.TicketID.Int32,
	)

	// Set ID from the DB raw:
	project.ID = string(appconfig.TicketID.Int32)

	_, err = qtx.CreateTicket(ctx, db.CreateTicketParams{
		Key:       pgtype.Text{String: project.Key, Valid: true},
		Channelid: pgtype.Text{String: project.ChannelID, Valid: true},
		Title:     pgtype.Text{String: project.Name, Valid: true},
	})
	if err != nil {
		tx.Rollback(ctx)
		return nil, err
	} else {
		tx.Commit(ctx)
	}

	return &project, nil
}

func (wc *WorkflowController) GetProjectByChannelID(ctx context.Context, id string) (*domain.Project, error) {

	dbTicket, err := wc.q.GetTicketByChannelID(ctx, pgtype.Text{String: id, Valid: true})
	if err != nil {
		if err == pgx.ErrNoRows {
			return nil, nil
		}
		return nil, err
	}

	return &domain.Project{
		ID:         strconv.Itoa(int(dbTicket.ID)),
		Key:        dbTicket.Key.String,
		Name:       dbTicket.Title.String,
		ChannelID:  dbTicket.Channelid.String,
		ProjectGit: dbTicket.ProjectGit.String,
		BuildGit:   dbTicket.BuildGit.String,
		Folder:     dbTicket.Folder.String,
	}, nil
}

// Saves current channel as project's channel;
func (wc *WorkflowController) InitProjectInChannel(ctx context.Context, channelID string, key string) (*domain.Project, error) {
	dbTicket, err := wc.q.GetTicketByChannelID(ctx, pgtype.Text{String: channelID, Valid: true})
	if err == pgx.ErrNoRows {
		dbTicket, err = wc.q.CreateTicket(
			ctx,
			db.CreateTicketParams{
				Key:       pgtype.Text{String: key, Valid: true},
				Channelid: pgtype.Text{String: channelID, Valid: true},
			},
		)
		if err != nil {
			return nil, err
		}
	} else {
		if err != nil {
			return nil, err
		}
	}

	return &domain.Project{
		ID:         string(dbTicket.ID),
		Key:        dbTicket.Key.String,
		Name:       dbTicket.Key.String,
		ChannelID:  dbTicket.Channelid.String,
		ProjectGit: dbTicket.ProjectGit.String,
		BuildGit:   dbTicket.BuildGit.String,
		Folder:     dbTicket.Folder.String,
	}, nil
}
