using Insight.Database;
using PlanTempus.Core;
using PlanTempus.Core.Entities.Accounts;
using System.Data;

namespace PlanTempus.Database.Core
{
    public class AccountService
    {
        public record AccountCreateCommand(string CorrelationId, string Email, string Password);

        private readonly IDbConnection _db;

        public AccountService(IDbConnection db)
        {
            _db = db;
        }

        public async Task CreateAccount(AccountCreateCommand command)
        {
            var account = new Account
            {
                Email = command.Email,
                PasswordHash = new SecureTokenizer().TokenizeText(command.Password),
                SecurityStamp = Guid.NewGuid().ToString(),
                EmailConfirmed = false,
                CreatedDate = DateTime.UtcNow
            };

            var accountId = await _db.ExecuteScalarAsync<int>(@$"
                INSERT INTO accounts (email, password_hash, security_stamp, email_confirmed, created_at)
                VALUES (@Email, @PasswordHash, @SecurityStamp, @EmailConfirmed, @CreatedDate)
                RETURNING id", account);
        }

        public async Task CreateOrganization(int accountId, string organizationConnectionString)
        {
            var schema = "dev";


            using var transaction = _db.OpenWithTransaction();
            try
            {
                // Create organization
                var organization = new Organization
                {
                    ConnectionString = organizationConnectionString,
                    CreatedDate = DateTime.UtcNow,
                    CreatedBy = accountId,
                    IsActive = true
                };

                var organizationId = await _db.ExecuteScalarAsync<int>(@$"
                INSERT INTO {schema}.organizations (connection_string, created_date, is_active)
                VALUES (@ConnectionString, @CreatedDate, @IsActive)
                RETURNING id", organization);

                // Link account to organization
                var accountOrganization = new AccountOrganization
                {
                    AccountId = accountId,
                    OrganizationId = organizationId,
                    CreatedDate = DateTime.UtcNow
                };

                await _db.ExecuteAsync(@$"
                INSERT INTO {schema}.account_organizations (account_id, organization_id, created_date)
                VALUES (@AccountId, @OrganizationId, @CreatedDate)", accountOrganization);

                transaction.Commit();
            }
            catch
            {
                transaction.Rollback();
                throw;
            }
        }
    }
}
