<?php

namespace Modules\MedAccounting\Database\Seeders;

use Carbon\Carbon;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Modules\MedAccounting\Entities\MedaccPeriod;
use Modules\MedAccounting\Services\AutoPostingService;

/**
 * Demo data for the 'Shifa One' business. Unlike a silent-skip demo seeder, this
 * one FALLS BACK gracefully: if 'Shifa One' is absent it logs a skip via
 * $this->command->warn (rather than returning silently) so the operator sees why
 * the demo GL is empty on a non-Shifa host.
 *
 * When the business is present it:
 *   1. Seeds the standard chart of accounts (idempotent, only if none exists).
 *   2. Runs AutoPostingService::backfill over the business's EXISTING ERP sells /
 *      payments / purchases / expenses / payroll so the demo trial balance is
 *      non-empty (never invents ERP data — reads what the platform already has).
 *   3. Opens the current month's accounting period.
 *
 * Everything is idempotent and fail-soft.
 */
class MedaccDemoSeeder extends Seeder
{
    public function run(): void
    {
        if (! Schema::hasTable('business') || ! Schema::hasTable('medacc_accounts')) {
            $this->warnOut('MedAccounting demo: core tables missing — skipped.');

            return;
        }

        $business = DB::table('business')->where('name', 'Shifa One')->first();
        if (empty($business)) {
            // Graceful fallback (not a silent return) — the operator learns why the demo GL is empty.
            $this->warnOut("MedAccounting demo: business 'Shifa One' not found on this host — demo GL not seeded.");

            return;
        }

        $businessId = (int) $business->id;

        // 1. Chart of accounts (only if the business has none).
        (new MedaccChartSeeder())->setContainer($this->container)
            ->setCommand($this->command)
            ->seedForBusiness($businessId);

        // 2. Open the current month's period.
        $start = Carbon::now()->startOfMonth();
        MedaccPeriod::firstOrCreate(
            ['business_id' => $businessId, 'name' => $start->format('Y-m')],
            [
                'start_date' => $start->toDateString(),
                'end_date'   => $start->copy()->endOfMonth()->toDateString(),
                'status'     => 'open',
            ]
        );

        // 3. Backfill journal entries from existing ERP events (idempotent).
        try {
            /** @var AutoPostingService $auto */
            $auto = app(AutoPostingService::class);
            $counts = $auto->backfill($businessId);
            $total = array_sum($counts);
            $this->infoOut("MedAccounting demo: chart seeded + current period opened for 'Shifa One'; backfilled {$total} journal entr(y/ies) "
                . "({$counts['invoice']} invoice, {$counts['payment']} payment, {$counts['purchase']} purchase, {$counts['expense']} expense, {$counts['payroll']} payroll).");
        } catch (\Throwable $e) {
            \Log::warning('MedAccounting demo backfill skipped: ' . $e->getMessage());
            $this->warnOut('MedAccounting demo: chart seeded, but auto-posting backfill was skipped (' . $e->getMessage() . ').');
        }
    }

    private function infoOut(string $msg): void
    {
        if ($this->command) {
            $this->command->info($msg);
        }
    }

    private function warnOut(string $msg): void
    {
        if ($this->command) {
            $this->command->warn($msg);
        }
    }
}
