<?php

namespace Database\Seeders\Demo\Concerns;

use App\Models\StockMovement;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;

/**
 * Shared helpers for the Demo\* seeders: Sri Lankan-flavoured fake data and
 * the backdating helper that spreads seeded documents across the last few
 * months so dashboards/reports show a realistic trend.
 */
trait GeneratesDemoData
{
    private array $usedNics = [];

    private array $usedPhones = [];

    /** Sri Lankan mobile number, e.g. 0771234567. */
    private function srPhone(): string
    {
        do {
            $prefix = fake()->randomElement(['070', '071', '072', '074', '075', '076', '077', '078']);
            $phone = $prefix.fake()->numerify('#######');
        } while (isset($this->usedPhones[$phone]));

        $this->usedPhones[$phone] = true;

        return $phone;
    }

    /** Sri Lankan landline, e.g. 0112345678. */
    private function landline(): string
    {
        $area = fake()->randomElement(['011', '081', '091', '038']);

        return $area.fake()->numerify('#######');
    }

    /** New-format 12-digit NIC. */
    private function nic(): string
    {
        do {
            $nic = fake()->numerify('#############');
            $nic = substr($nic, 0, 12);
        } while (isset($this->usedNics[$nic]));

        $this->usedNics[$nic] = true;

        return $nic;
    }

    private function businessName(): string
    {
        $suffix = fake()->randomElement([
            'Traders', 'Enterprises', '(Pvt) Ltd', 'Stores', 'Distributors',
            'Holdings', 'Retail', 'Trading Co', 'Mart', 'Ventures',
        ]);

        return fake()->lastName().' '.$suffix;
    }

    /** Weighted-random date in the last N months, biased toward recent activity. */
    private function recentDate(int $months = 6): Carbon
    {
        $daysBack = (int) round((mt_rand(0, 1000) / 1000) ** 1.6 * $months * 30);

        return Carbon::now()->subDays($daysBack)->setTime(mt_rand(8, 19), mt_rand(0, 59), mt_rand(0, 59));
    }

    /**
     * Backdate a document's timestamps (and, optionally, the StockMovement
     * rows it directly caused) to make report/dashboard trends realistic.
     * Uses saveQuietly() so no model events / audit re-stamping fire.
     */
    private function backdate(Model $doc, Carbon $date, bool $cascadeStockMovements = false): void
    {
        $doc->forceFill(['created_at' => $date, 'updated_at' => $date])->saveQuietly();

        if ($cascadeStockMovements) {
            StockMovement::query()
                ->where('reference_type', $doc::class)
                ->where('reference_id', $doc->getKey())
                ->update(['created_at' => $date]);
        }
    }
}
