using System.Data;
using Insight.Database;

namespace PlanTempus.Database.RolesPermissionSystem
{
    /// <summary>
    /// This is by purpose not async await
    /// It is intended that this is created with the correct Application User, which is why the schema name is omitted.
    /// </summary>
    public class Setup
    {
        IDbConnection _db;

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

        /// <summary>
        /// Creates the system tables in the specified schema within a transaction.
        /// </summary>
        /// <param name="schema">The schema name where the tables will be created.</param>
        public void CreateSystem()
        {
            //if (!Validations.IsValidSchemaName(_schema))
            //    throw new ArgumentException("Invalid schema name", _schema);

            using var transaction = _db.BeginTransaction();
            try
            {
                CreateRolesTable();
                CreatePermissionsTable();
                CreatePermissionTypesTable();
                CreateRolePermissionsTable();

                transaction.Commit();
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                throw new InvalidOperationException("Failed to create system tables.", ex);
            }
        }


        private void ExecuteSql(string sql)
        {
            _db.ExecuteSql(sql);
        }

        private void CreatePermissionTypesTable()
        {
            var sql = $@"
            CREATE TABLE IF NOT EXISTS permission_types (
                id SERIAL PRIMARY KEY,
                name VARCHAR(100) NOT NULL UNIQUE
            )";
            ExecuteSql(sql);
        }

        private void CreatePermissionsTable()
        {
            var sql = $@"
            CREATE TABLE IF NOT EXISTS permissions (
                id SERIAL PRIMARY KEY,
                name VARCHAR(100) NOT NULL UNIQUE,
                type_id INTEGER NOT NULL,
                FOREIGN KEY (type_id) REFERENCES permission_types(id)
            )";
            ExecuteSql(sql);
        }

        private void CreateRolesTable()
        {
            var sql = $@"
            CREATE TABLE IF NOT EXISTS roles (
                id SERIAL PRIMARY KEY,
                name VARCHAR(100) NOT NULL UNIQUE
            )";
            ExecuteSql(sql);
        }

        private void CreateRolePermissionsTable()
        {
            var sql = $@"
            CREATE TABLE IF NOT EXISTS role_permissions (
                role_id INTEGER NOT NULL,
                permission_id INTEGER NOT NULL,
                PRIMARY KEY (role_id, permission_id),
                FOREIGN KEY (role_id) REFERENCES roles(id),
                FOREIGN KEY (permission_id) REFERENCES permissions(id)
            )";
            ExecuteSql(sql);
        }
    }
}