package database

import (
	"context"
	"os"
	"strings"

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

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

var Client *ent.Client

func AddFakeData() {

	_, 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.wiki/Frequently_asked_questions"}).
		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).
		SetScore(10).
		SetType(service.TypeExchange).
		SetAttributes(strings.Join([]string{AttributeNonCustodialWallet, AttributeOpenSource, AttributeNoPersonalInfoNeeded, AttributeP2P}, ",")).
		SetTosHighlights(nil).
		Save(context.Background())

	if err != nil {
		log.Error().Err(err).Msg("Could not save service to database")
	}

	_, _ = 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/nojs/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).
		SetScore(10).
		SetType(service.TypeExchange).
		SetAttributes(strings.Join([]string{AttributeNonCustodialWallet, AttributeOpenSource, AttributeNoPersonalInfoNeeded, AttributeP2P}, ",")).
		SetTosHighlights(nil).
		Save(context.Background())

	_, _ = Client.Service.Create().
		SetName("mullvad").
		SetLogoURL("https://kycnot.me/static/img/mullvad.webp").
		SetDescription("VPN service. Strict no-logs, open-source clients.").
		SetUrls([]string{"https://mullvad.net/"}).
		SetTosUrls([]string{"https://mullvad.net/en/help/terms-service/"}).
		SetOnionUrls([]string{"http://o54hon2e2vj6c7m3aqqu6uyece65by3vgoxxhlqlsvkmacw6a7m7kiad.onion/en/"}).
		SetKycLevel(0).
		SetTags("vpn,private,secure,safe").
		SetPending(false).
		SetListed(true).
		SetVerified(true).
		SetXmr(true).
		SetBtc(true).
		SetLightning(false).
		SetFiat(true).
		SetCash(true).
		SetType(service.TypeService).
		SetCategory("VPN").
		SetScore(10).
		SetAttributes(strings.Join([]string{AttributeStrictNoKYCPolicy, AttributeStrictNoLogPolicy, AttributeNoRegistrationNeeded, AttributeOpenSource, AttributeMobileAppAvailable, AttributeNoJavaScriptNeeded}, ",")).
		SetTosHighlights(nil).
		Save(context.Background())

	_, _ = Client.Service.Create().
		SetName("fixedfloat").
		SetLogoURL("https://kycnot.me/static/img/fixedfloat.webp").
		SetDescription("Instant, fully automatic cryptocurrency exchange with Lightning Network.").
		SetUrls([]string{"https://fixedfloat.com/"}).
		SetTosUrls([]string{"https://fixedfloat.com/terms-of-service"}).
		SetOnionUrls([]string{}).
		SetKycLevel(2).
		SetTags("swap,fast,no account").
		SetListingComments([]string{"This is a sample listing comment."}).
		SetPending(false).
		SetListed(true).
		SetVerified(false).
		SetXmr(true).
		SetBtc(true).
		SetLightning(true).
		SetFiat(false).
		SetCash(false).
		SetType(service.TypeExchange).
		SetCategory("").
		SetScore(6).
		SetAttributes(strings.Join([]string{AttributeRiskPreventionSystem, AttributeKYCIfObligedByLaw, AttributePrivateSourceCode, AttributeRefundRequiresKYC, AttributeNonCustodialWallet, AttributeNoRegistrationNeeded, AttributeAPIAvailable, AttributeJavaScriptNeeded}, ",")).
		SetTosHighlights(nil).
		Save(context.Background())

	_, _ = Client.Service.Create().
		SetName("coinswap").
		SetLogoURL("https://kycnot.me/static/img/coinswap.webp").
		SetDescription("Simple and light swap page where you can swap various cryptos.").
		SetUrls([]string{"https://coinswap.click/"}).
		SetTosUrls([]string{"https://coinswap.click/faq/"}).
		SetOnionUrls([]string{}).
		SetKycLevel(1).
		SetTags("swap,fast,no account,nojs,light").
		SetPending(false).
		SetListed(true).
		SetVerified(true).
		SetXmr(true).
		SetBtc(true).
		SetLightning(true).
		SetFiat(false).
		SetCash(false).
		SetType(service.TypeExchange).
		SetCategory("").
		SetScore(8).
		SetAttributes(strings.Join([]string{AttributeKYCIfObligedByLaw, AttributePrivateSourceCode, AttributeRefundRequiresKYC, AttributeNonCustodialWallet, AttributeNoRegistrationNeeded, AttributeAPIAvailable, AttributeNoJavaScriptNeeded}, ",")).
		SetTosHighlights(nil).
		Save(context.Background())
}
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" && config.Conf.Dev {
		log.Debug().Msg("Adding fake data to DB")
		AddFakeData()
	}
}

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