<?php

namespace Istlab\AdminCrud\Support;

use Illuminate\Support\Facades\DB;

class Schema
{
    /**
     * 現在の接続のテーブル名一覧を返す。
     *
     * @return array<int, string>
     */
    public static function tables(): array
    {
        $driver = DB::connection()->getDriverName();
        if (in_array($driver, ['sqlite', 'sqlite_testing'], true)) {
            $rows = DB::select("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'");
            $tables = array_map(fn ($item) => $item->name, $rows);
        } else {
            $rows = DB::select('SHOW TABLES');
            $tables = [];
            foreach ($rows as $obj) {
                foreach ($obj as $tn) {
                    $tables[] = $tn;
                }
            }
        }
        sort($tables);

        return $tables;
    }

    /**
     * カラム名 => データ型 (かっこ以下は除去) の連想配列を返す。
     *
     * @return array<string, string>
     */
    public static function columnDetails(string $tableName): array
    {
        $driver = DB::connection()->getDriverName();
        $coldetails = [];
        if (in_array($driver, ['sqlite', 'sqlite_testing'], true)) {
            $columns = DB::select("pragma table_info('{$tableName}')");
            foreach ($columns as $cc) {
                $coldetails[$cc->name] = (string) $cc->type;
            }
        } else {
            $columns = DB::select("show full columns from `{$tableName}`");
            foreach ($columns as $colary) {
                $coldetails[$colary->Field] = $colary->Type;
            }
        }
        // Type() のかっこ以下は取り除く
        foreach ($coldetails as $f => $t) {
            $pos = strpos($t, '(');
            if ($pos > 0) {
                $coldetails[$f] = substr($t, 0, $pos);
            }
        }

        return $coldetails;
    }

    /**
     * カラム名 => カラムコメント (MySQL) またはカラム名 (SQLite) の連想配列を返す。
     *
     * @return array<string, string>
     */
    public static function tableComments(string $dbName, string $tableName): array
    {
        $driver = DB::connection()->getDriverName();
        $coldetails = [];
        if (in_array($driver, ['sqlite', 'sqlite_testing'], true)) {
            $columns = DB::select("pragma table_info('{$tableName}')");
            foreach ($columns as $cc) {
                $coldetails[$cc->name] = $cc->name;
            }
        } else {
            $columns = DB::select("SELECT COLUMN_NAME, COLUMN_COMMENT FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '{$dbName}' AND TABLE_NAME = '{$tableName}'");
            foreach ($columns as $colary) {
                $coldetails[$colary->COLUMN_NAME] = $colary->COLUMN_COMMENT;
            }
        }

        return $coldetails;
    }
}
