<?php

namespace Amwdeveloper\model;

use Amwdeveloper\controller\connection;
use PDOException;

class layer extends connection
{
    /** @var object|null */
    protected $data;

    /** @var \PDOException */
    protected $fail;

    protected $table;

    protected $params;

    protected $columns = "*";

    protected $where;

    protected $orderby;

    protected $limit;

    protected $inner;

    public function __get($name)
    {
        return ($this->data->$name ?? null);
    }

    public function __set($name, $value)
    {
        if (empty($this->data)) {
            $this->data = new \stdClass();
        }
        return $this->data->$name = $value;
    }

    public function __isset($name)
    {
        return isset($this->data->$name);
    }

    public function data(): ?object
    {
        return $this->data;
    }

    public function fail(): ?PDOException
    {
        return $this->fail;
    }

    public function table(string $table): layer
    {
        $this->table = " {$table}";
        return $this;
    }

    public function columns(string $column = "*"): layer
    {
        $this->columns = " {$column}";
        return $this;
    }

    public function where(string $where, string $params): layer
    {
        $this->where = " WHERE {$where}";
        parse_str($params, $this->params);
        return $this;
    }

    public function orderby(string $order, string $type = "DESC"): layer
    {
        $this->orderby = " ORDER BY {$order} {$type}";
        return $this;
    }

    public function limit(int $limit = 10): layer
    {
        $this->limit = " TOP {$limit}";
        return $this;
    }
	public function group(string $group): layer
	{
		$this->group = " GROUP BY {$group}";
		return $this;
	}
	
    public function inner(string $inner)
    {
        $this->inner = " {$inner}";
        return $this;
    }

    public function count()
    {
        try {
            $stmt = $this->db()->prepare("SELECT COUNT({$this->columns}) as amount FROM {$this->table} {$this->where}");
            $stmt->execute($this->params);
            $this->where = null;
            $this->columns = "*";
            $this->params = null;
            $this->table = null;
            return $stmt->fetchObject(static::class);
        } catch (\PDOException $e) {
            $this->fail = $e;
            return null;
        }
    }

    public function get()
    {
        try {
            $stmt = $this->db()->prepare("SELECT {$this->limit} {$this->columns} FROM {$this->table} {$this->inner} {$this->where} {$this->orderby}");
            $stmt->execute($this->params);
            $this->where = null;
            $this->limit = null;
            $this->columns = "*";
            $this->orderby = null;
            $this->params = null;
            $this->inner = null;
            $this->table = null;
            return $stmt->fetchObject(static::class);
        } catch (\PDOException $e) {
            $this->fail = $e;
            return null;
        }
    }

    public function all()
    {
        try {
            $stmt = $this->db()->prepare("SELECT {$this->limit} {$this->columns} FROM {$this->table} {$this->inner} {$this->where} {$this->orderby}");
            $stmt->execute($this->params);
            $this->where = null;
            $this->limit = null;
            $this->columns = "*";
            $this->orderby = null;
            $this->params = null;
            $this->inner = null;
            $this->table = null;
            return $stmt->fetchAll(\PDO::FETCH_CLASS, static::class);
        } catch (\PDOException $e) {
            $this->fail = $e;
            return null;
        }
    }

    public function created($data)
    {
        try {
            $keys = implode(", ", array_keys($data));
            $values = ":" . implode(", :", array_keys($data));

            $stmt = $this->db()->prepare("INSERT INTO {$this->table} ({$keys}) VALUES ({$values})");
            $stmt->execute($data);
            $this->table = null;
            return $this->db()->lastInsertId();
        } catch (\PDOException $e) {
            $this->fail = $e;
            return null;
        }
    }

    public function updated($data)
    {
        try {
            $newData = array();
            foreach ($data as $bind => $value) {
                $newData[] = "{$bind} = :{$bind}";
            }
            $newData = implode(", ", $newData);
            $stmt = $this->db()->prepare("UPDATE {$this->table}  SET {$newData} {$this->where}");
            $stmt->execute(array_merge($data, $this->params));
            $this->table = null;
            $this->where = null;
            $this->params = null;
            return ($stmt->rowCount ?? 1);
        } catch (\PDOException $e) {
            $this->fail = $e;
            return null;
        }
    }

    public function destroy()
    {
        try {
            $stmt = $this->db()->prepare("DELETE FROM {$this->table} {$this->where}");
            $stmt->execute($this->params);
            $this->table = null;
            $this->where = null;
            $this->params = null;
            return ($stmt->rowCount ?? 1);
        } catch (\PDOException $e) {
            $this->fail = $e;
            return null;
        }
    }
	
	public function getDonations()
    {
        try {
            // Prepara a consulta SQL
            $stmt = $this->db()->prepare("
                SELECT TOP 5 Account, SUM(Price) AS TotalPrice
                FROM amw_payment_mp
                WHERE status = 1 AND
				YEAR(due_date) = YEAR(GETDATE()) AND
				MONTH(due_date) = MONTH(GETDATE())
                GROUP BY Account
                ORDER BY TotalPrice DESC
            ");

            // Executa a consulta
            $stmt->execute();

            // Retorna os resultados como uma lista de objetos
            return $stmt->fetchAll(\PDO::FETCH_OBJ);
        } catch (PDOException $e) {
            // Em caso de erro, retorna null e exibe a mensagem de erro
            echo "Erro ao executar a consulta: " . $e->getMessage();
            return null;
        }
    }

	
}
