using LevelCode.License.Models;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;

namespace LevelCode.License.DataAccess
{
    public class LicencaDAL
    {
        private readonly DbConexao _db;

        public LicencaDAL(DbConexao db)
        {
            _db = db;
        }

        // =========================
        // INSERIR LICENÇA
        // =========================
        public int Inserir(ModeloLicenca modelo)
        {
            if (modelo == null)
                throw new ArgumentNullException(nameof(modelo));

            if (string.IsNullOrWhiteSpace(modelo.LicenseKey))
                throw new Exception("LicenseKey não foi gerado.");

            SqlCommand cmd = new SqlCommand(
                @"INSERT INTO Licencas
                  (LicenseKey, Cliente, TipoLicenca, CodigoTipoLicenca,
                   ExpiraEm, LimiteMaquinas, Modulos, Status, DataCriacao)
                  VALUES
                  (@LicenseKey, @Cliente, @TipoLicenca, @CodigoTipoLicenca,
                   @ExpiraEm, @LimiteMaquinas, @Modulos, @Status, @DataCriacao);
                  SELECT SCOPE_IDENTITY();",
                _db.Conexao);

            cmd.Parameters.AddWithValue("@LicenseKey", modelo.LicenseKey);
            cmd.Parameters.AddWithValue("@Cliente", (object)modelo.Cliente ?? DBNull.Value);
            cmd.Parameters.AddWithValue("@TipoLicenca", (object)modelo.TipoLicenca ?? DBNull.Value);
            cmd.Parameters.AddWithValue("@CodigoTipoLicenca", modelo.CodigoTipoLicenca);
            cmd.Parameters.AddWithValue("@ExpiraEm", (object)modelo.ExpiraEm ?? DBNull.Value);
            cmd.Parameters.AddWithValue("@LimiteMaquinas", modelo.LimiteMaquinas);
            cmd.Parameters.AddWithValue("@Modulos", (object)modelo.Modulos ?? "[]");
            cmd.Parameters.AddWithValue("@Status", modelo.Status);
            cmd.Parameters.AddWithValue("@DataCriacao", modelo.DataCriacao);

            _db.Abrir();
            int id = Convert.ToInt32(cmd.ExecuteScalar());
            _db.Fechar();

            return id;
        }

        // =========================
        // BUSCAR LICENÇA POR KEY
        // =========================
        public ModeloLicenca BuscarPorLicenseKey(string licenseKey)
        {
            SqlCommand cmd = new SqlCommand(
                @"SELECT * FROM Licencas
                  WHERE LicenseKey = @LicenseKey",
                _db.Conexao);

            cmd.Parameters.AddWithValue("@LicenseKey", licenseKey);

            _db.Abrir();
            SqlDataReader dr = cmd.ExecuteReader();

            ModeloLicenca modelo = null;

            if (dr.Read())
                modelo = Mapear(dr);

            dr.Close();
            _db.Fechar();

            return modelo;
        }

        // =========================
        // BUSCAR LICENÇA ATIVA POR CLIENTE
        // =========================
        public ModeloLicenca BuscarLicencaAtivaPorCliente(string cliente)
        {
            SqlCommand cmd = new SqlCommand(
                @"SELECT TOP 1 *
                  FROM Licencas
                  WHERE Cliente = @Cliente
                    AND Status = 1
                  ORDER BY DataCriacao DESC",
                _db.Conexao);

            cmd.Parameters.AddWithValue("@Cliente", cliente);

            _db.Abrir();
            SqlDataReader dr = cmd.ExecuteReader();

            ModeloLicenca modelo = null;

            if (dr.Read())
                modelo = Mapear(dr);

            dr.Close();
            _db.Fechar();

            return modelo;
        }

        // =========================
        // BUSCAR TODAS AS LICENÇAS
        // =========================
        public List<ModeloLicenca> BuscarTodas()
        {
            List<ModeloLicenca> lista = new List<ModeloLicenca>();

            SqlCommand cmd = new SqlCommand(
                @"SELECT *
                  FROM Licencas
                  ORDER BY DataCriacao DESC",
                _db.Conexao);

            _db.Abrir();
            SqlDataReader dr = cmd.ExecuteReader();

            while (dr.Read())
            {
                lista.Add(Mapear(dr));
            }

            dr.Close();
            _db.Fechar();

            return lista;
        }

        // =========================
        // ATUALIZAR STATUS
        // =========================
        public void AtualizarStatus(int idLicenca, int status)
        {
            SqlCommand cmd = new SqlCommand(
                @"UPDATE Licencas
                  SET Status = @Status
                  WHERE IdLicenca = @Id",
                _db.Conexao);

            cmd.Parameters.AddWithValue("@Status", status);
            cmd.Parameters.AddWithValue("@Id", idLicenca);

            _db.Abrir();
            cmd.ExecuteNonQuery();
            _db.Fechar();
        }

        // =========================
        // MAPEAR DATAREADER → MODELO
        // =========================
        private ModeloLicenca Mapear(SqlDataReader dr)
        {
            return new ModeloLicenca
            {
                IdLicenca = Convert.ToInt32(dr["IdLicenca"]),
                LicenseKey = dr["LicenseKey"] as string,
                Cliente = dr["Cliente"] as string,
                TipoLicenca = dr["TipoLicenca"] as string,
                CodigoTipoLicenca = dr["CodigoTipoLicenca"] != DBNull.Value
                    ? Convert.ToInt32(dr["CodigoTipoLicenca"])
                    : 0,
                ExpiraEm = dr["ExpiraEm"] != DBNull.Value
                    ? (DateTime?)Convert.ToDateTime(dr["ExpiraEm"])
                    : null,
                LimiteMaquinas = Convert.ToInt32(dr["LimiteMaquinas"]),
                Modulos = dr["Modulos"] as string,
                Status = Convert.ToInt32(dr["Status"]),
                DataCriacao = Convert.ToDateTime(dr["DataCriacao"]),
                UltimaSincronizacao = dr["UltimaSincronizacao"] != DBNull.Value
                    ? (DateTime?)Convert.ToDateTime(dr["UltimaSincronizacao"])
                    : null
            };
        }
    }
}
