<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;

class GenerateSchemaCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'app:schema-generate';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Generate a schema.md file documenting all database tables';

    /**
     * Execute the console command.
     */
    public function handle(): int
    {
        $this->info('Generating database schema documentation...');

        // Get all tables
        $tables = DB::select('SHOW TABLES');
        $tableKey = 'Tables_in_'.DB::getDatabaseName();

        $tableNames = [];
        foreach ($tables as $table) {
            $tableNames[] = $table->$tableKey;
        }

        // Sort tables alphabetically
        sort($tableNames);

        // Build markdown content
        $markdown = "# Database Schema Documentation\n\n";
        $markdown .= '> Generated: '.date('Y-m-d H:i:s')."\n";
        $markdown .= '> Database: '.DB::getDatabaseName()."\n";
        $markdown .= '> Total Tables: '.count($tableNames)."\n\n";
        $markdown .= "## Table of Contents\n\n";

        // Add table of contents
        foreach ($tableNames as $tableName) {
            $markdown .= "- [{$tableName}](#{$tableName})\n";
        }
        $markdown .= "\n---\n\n";

        // Process each table
        foreach ($tableNames as $tableName) {
            $this->line("Processing table: {$tableName}");

            $markdown .= "## {$tableName}\n\n";

            // Get columns
            $columns = DB::select("SHOW COLUMNS FROM `{$tableName}`");

            // Get foreign keys
            $foreignKeys = DB::select('
                SELECT
                    CONSTRAINT_NAME,
                    COLUMN_NAME,
                    REFERENCED_TABLE_NAME,
                    REFERENCED_COLUMN_NAME
                FROM
                    INFORMATION_SCHEMA.KEY_COLUMN_USAGE
                WHERE
                    TABLE_NAME = ?
                    AND TABLE_SCHEMA = DATABASE()
                    AND REFERENCED_TABLE_NAME IS NOT NULL
            ', [$tableName]);

            // Build FK lookup array
            $fkLookup = [];
            foreach ($foreignKeys as $fk) {
                $fkLookup[$fk->COLUMN_NAME] = [
                    'table' => $fk->REFERENCED_TABLE_NAME,
                    'column' => $fk->REFERENCED_COLUMN_NAME,
                    'constraint' => $fk->CONSTRAINT_NAME,
                ];
            }

            // Build columns table
            $markdown .= "| Field | Type | Null | Key | Default | Extra | Foreign Key |\n";
            $markdown .= "|-------|------|------|-----|---------|-------|-------------|\n";

            foreach ($columns as $column) {
                $fkInfo = '';
                if (isset($fkLookup[$column->Field])) {
                    $fk = $fkLookup[$column->Field];
                    $fkInfo = "→ {$fk['table']}.{$fk['column']}";
                }

                $markdown .= "| {$column->Field} | {$column->Type} | {$column->Null} | {$column->Key} | ";
                $markdown .= ($column->Default === null ? 'NULL' : $column->Default).' | ';
                $markdown .= "{$column->Extra} | {$fkInfo} |\n";
            }

            // Add foreign key details if any
            if (! empty($foreignKeys)) {
                $markdown .= "\n### Foreign Key Constraints\n\n";
                foreach ($foreignKeys as $fk) {
                    $markdown .= "- **{$fk->CONSTRAINT_NAME}**: `{$fk->COLUMN_NAME}` → `{$fk->REFERENCED_TABLE_NAME}.{$fk->REFERENCED_COLUMN_NAME}`\n";
                }
            }

            $markdown .= "\n---\n\n";
        }

        // Ensure directory exists
        $directory = base_path('database');
        if (! File::exists($directory)) {
            File::makeDirectory($directory, 0755, true);
        }

        // Write to file
        $filePath = $directory.'/schema.md';
        File::put($filePath, $markdown);

        $this->info('✅ Schema documentation generated successfully!');
        $this->line("📄 File saved to: {$filePath}");

        return Command::SUCCESS;
    }
}
