<?php
namespace Helpers\QueryBuilder;

enum JoinType
{
    case Left;
    case Right;
    case Inner;
    case Outer;
}

abstract class SqlJoin extends AbsSqlFragment
{
    private JoinType $type;

    /** @var string|ISqlFragment */
    private $table;

    /** @var array<string|ISqlFragment> */
    private array $listClause;

    private ?string $alias;

    /**
     * @param string|ISqlFragment $table
     * @param array<string|ISqlFragment> $listClause
     */
    public function __construct(
        JoinType $type,
        $table,
        array $listClause = [],
        ?string $alias = null
    ) {
        $this->type = $type;
        $this->table = $table;
        $this->listClause = $listClause;
        $this->alias = $alias;
    }

    private function getTypeSql() :string
    {
        switch ($this->type) {
            case JoinType::Left:
                return 'LEFT JOIN';
            case JoinType::Right:
                return 'RIGHT JOIN';
            case JoinType::Inner:
                return 'JOIN';
            case JoinType::Outer:
                return 'OUTER JOIN';
        }
        throw new \Exception('Invalid type');
    }

    public function __tostring()
    {
        return implode(' ', [
            $this->getTypeSql(),
            (string) $this->table,
            ($this->alias ? ' as ' . $this->alias : ''),
            'with(nolock)',
            'ON',
            implode(' AND ', $this->listClause)
        ]);
    }
}
