package database

import (
	"context"
	"os"
	"strings"

	_ "github.com/mattn/go-sqlite3"
	"github.com/rs/zerolog/log"

	"pluja.dev/kycnot.me/ent"
	"pluja.dev/kycnot.me/ent/schema"
	"pluja.dev/kycnot.me/ent/service"
)

var Client *ent.Client

func AddFakeData() {
	sampleTosHighlight := schema.TosHighlight{
		Title:     "Transaction monitoring",
		Text:      "MEX relies on data analysis as a risk-assessment and suspicion detection tool. MEX performs a variety of compliance-related tasks, including capturing data, filtering, record-keeping, investigation management, and reporting.",
		Reference: "https://example.com/tos",
	}

	_, err := Client.Service.Create().
		SetName("bisq").
		SetLogoURL("https://kycnot.me/static/img/bisq.webp").
		SetDescription("Buy and sell bitcoin for fiat (or cryptocurrencies) privately and securely using Bisq's peer-to-peer network and open-source desktop software.").
		SetUrls([]string{"https://bisq.network/"}).
		SetTosUrls([]string{"https://bisq.network/privacy-policy/"}).
		SetOnionUrls([]string{}).
		SetKycLevel(0).
		SetTags("market,p2p,buy,sell,anonymous").
		SetPending(false).
		SetListed(true).
		SetVerified(true).
		SetXmr(true).
		SetBtc(true).
		SetLightning(true).
		SetFiat(true).
		SetCash(true).
		SetType(service.TypeExchange).
		SetAttributes(strings.Join([]string{AttributeNonCustodialWallet, AttributeOpenSource, AttributeNoPersonalInfoNeeded, AttributeP2P, AttributeAPIAvailable, AttributePartnersMayEnforceKYC, AttributeBlockFundsIfFlagged, AttributeKYCForSomeFeatures}, ",")).
		SetTosHighlights(&[]schema.TosHighlight{sampleTosHighlight}).
		Save(context.Background())
	if err != nil {
		log.Fatal().Msgf("failed creating service: %v", err)
	}

	_, err = Client.Service.Create().
		SetName("localmonero").
		SetLogoURL("https://kycnot.me/static/img/localmonero.webp").
		SetDescription("Peer-to-peer Monero trading platform. A marketplace where users can buy and sell Monero to and from each other. You'll be able to buy and sell online with more than 60 currencies.").
		SetUrls([]string{"https://localmonero.co/"}).
		SetTosUrls([]string{"https://localmonero.co/faq"}).
		SetOnionUrls([]string{"http://nehdddktmhvqklsnkjqcbpmb63htee2iznpcbs5tgzctipxykpj6yrid.onion/"}).
		SetKycLevel(1).
		SetTags("market,p2p,buy,sell").
		SetPending(false).
		SetListed(true).
		SetVerified(true).
		SetXmr(true).
		SetBtc(true).
		SetLightning(false).
		SetFiat(true).
		SetCash(true).
		SetType(service.TypeExchange).
		SetAttributes(strings.Join([]string{AttributeNonCustodialWallet, AttributeOpenSource, AttributeNoPersonalInfoNeeded, AttributeP2P}, ",")).
		SetTosHighlights(&[]schema.TosHighlight{sampleTosHighlight}).
		Save(context.Background())
	if err != nil {
		log.Fatal().Msgf("failed creating service: %v", err)
	}
}
func InitDb() {
	var err error

	if os.Getenv("DB_TYPE") == "sqlite" {
		Client, err = ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
		if err != nil {
			log.Fatal().Msgf("failed opening connection to sqlite: %v", err)
		}
	} else if os.Getenv("DB_TYPE") == "mysql" {
		Client, err = ent.Open("mysql", os.Getenv("DB_USER")+":"+os.Getenv("DB_PASS")+"@tcp("+os.Getenv("DB_HOST")+":"+os.Getenv("DB_PORT")+")/"+os.Getenv("DB_NAME"))
		if err != nil {
			log.Fatal().Msgf("failed opening connection to mysql: %v", err)
		}
	} else if os.Getenv("DB_TYPE") == "postgres" {
		Client, err = ent.Open("postgres", "host="+os.Getenv("DB_HOST")+" port="+os.Getenv("DB_PORT")+" user="+os.Getenv("DB_USER")+" dbname="+os.Getenv("DB_NAME")+" password="+os.Getenv("DB_PASS")+" sslmode=disable")
		if err != nil {
			log.Fatal().Msgf("failed opening connection to postgres: %v", err)
		}
	} else {
		log.Fatal().Msgf("failed opening connection to database: %v", err)
	}
	if err := Client.Schema.Create(context.Background()); err != nil {
		panic(err)
	}

	// Run the auto migration tool.
	ctx := context.Background()
	if err := Client.Schema.Create(ctx); err != nil {
		log.Fatal().Msgf("failed creating schema resources: %v", err)
	}

	if os.Getenv("DB_TYPE") == "sqlite" && os.Getenv("DEV_MODE") == "true" {
		AddFakeData()
	}
}

func Close() {
	if err := Client.Close(); err != nil {
		log.Fatal().Msgf("failed closing database connection: %v", err)
	}
}
