<?php

namespace Database\Seeders;

use App\Models\Subscription;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

use App\Models\Settings\RegionalSettings\Nationality;
use App\Models\Customer;

use Carbon\Carbon;

class DatabaseSeeder extends Seeder
{
    use WithoutModelEvents;

    public function run(): void
    {
        $this->call([
            RegionsSeeder::class,
            CitiesSeeder::class,
            NationalitiesSeeder::class,
            PaymentMethodSeeder::class,
            BanksSeeder::class,

            PermissionSeeder::class,
            UserSeeder::class,

            SettingsSeeder::class,

//            PlanSeeder::class,
//            CustomerSeeder::class,
//            SubscriptionSeeder::class,
//            ReceiptVoucherSeeder::class,
//            PaymentVoucherSeeder::class,
//            CustomerBalanceSeeder::class,
//            CustomerBalanceTransactionSeeder::class,
//            AttendanceSeeder::class,
        ]);


        DB::connection('mysql-2')->table('plans')->orderBy('id')
            ->chunk(100, function ($plans) {

                foreach ($plans as $plan) {

                    DB::connection('mysql')->table('plans')->insert([
                        'name_ar' => $plan->name ?? '',
                        'name_en' => $plan->name2 ?? $plan->name ?? '',
                        'description' => $plan->notes ?? null,
                        'price' => is_numeric($plan->amount) ? $plan->amount : 0,
                        'duration_days' => is_numeric($plan->days) ? (int) $plan->days : 0,
                        'sessions_count' => is_numeric($plan->count) ? (int) $plan->count : null,
                        'type' => $this->mapPlanType($plan->days, $plan->count),
                        'is_active' => ($plan->status == 'ON') ? 1 : 0,
                        'created_at' => now(),
                        'updated_at' => now(),
                        'created_by' => 1,
                    ]);
                }
            });

        $nationalities = Nationality::pluck('id', 'country_ar');

        DB::connection('mysql-2')
            ->table('rsclients')
            ->orderBy('id')
            ->chunk(100, function ($clients) use ($nationalities) {

                $insertData = [];
                $newNumber = 1;

                foreach ($clients as $client) {
                    $height = $this->cleanHeight($client->height);
                    $weight = $this->cleanWeight($client->weight);

                    $bmi = null;
                    if (is_numeric($height) && is_numeric($weight)) {
                        $heightM = $height / 100;
                        $bmi = $weight / ($heightM * $heightM);
                    }

                    $registrationDate = $this->parseDate($client->datetime);

                    $year = now()->format('Y');
                    $month = now()->format('m');

                    $nationalityName = DB::connection('mysql-2')
                        ->table('nationalities')
                        ->where('id', $client->id_nat)
                        ->value('name');

                    $nationalityId = $nationalities[$nationalityName] ?? null;

                    $insertData[] = [
                        'id' => $client->id ?? null,
                        'code' => 'MEM' . $year.$month . str_pad($newNumber, 3, '0', STR_PAD_LEFT),
                        'name' => $client->name ?? null,
                        'country_code_id' => $nationalityId ?? null,
                        'mobile' => $this->cleanNumber($client->mobile),
                        'address' => $client->address ?? null,
                        'gender' => 1,
                        'notes' => $client->notes ?? null,
                        'height' => $height ?: null,
                        'weight' => $weight ?: null,
                        'bmi' => $bmi,
                        'national_id' => $this->cleanNumber($client->nat),
                        'nationality_id' => $nationalityId ?? null,
                        'registration_date' => $registrationDate,
                        'emergency_contact' => $this->cleanNumber($client->mobile2),
                        'avatar' => null,
                        'is_active' => true,
                        'created_at' => now(),
                        'created_by' => 1,
                    ];
                    ++$newNumber;
                }

                DB::connection('mysql')->table('customers')->insert($insertData);
            });

        $orders = DB::connection('mysql-2')->table('tkorders')->get();

        $newNumber = 1;
        foreach ($orders as $order) {
            $totalAmount = is_numeric($order->total) ? $order->total : 0;

            if (!Customer::find($order->id_client)) {
                continue;
            }

            $endDate = $this->parseDate($order->e_date);
            $today = Carbon::today();

            if ($endDate < $today) {
                $subscriptionStatus = 'expired';
            } elseif ($endDate > $today) {
                $subscriptionStatus = 'active';
            } else {
                $subscriptionStatus = 'canceled';
            }

            $vat = is_numeric($order->vat_am) ? $order->vat_am : 0;

            $year = now()->format('Y');
            $month = now()->format('m');
            $defaultCode = settings('invoice_prefix') ?? 'INV';

            $subscriptionData = [
                'code' => $defaultCode . $year.$month . str_pad($newNumber, 3, '0', STR_PAD_LEFT),
                'customer_id' => $order->id_client,
                'plan_id' => $order->id_service,
                'start_date' => $this->parseDate($order->s_date),
                'end_date' => $this->parseDate($order->e_date),
                'amount' => (float) $totalAmount,
                'discount' => 0.00,
                'net_amount' => (float) $totalAmount,
                'vat' => $vat,
                'vat_value' => ($vat > 0) ? (float) $totalAmount / $vat * 100 : 0.00,
                'total' => (float) $totalAmount,
                'amount_paid' => (float) $totalAmount,
                'remaining_paid' => 0,
                'vat_included' => ($order->vat == 'ON') ? 1 : 0,
                'sessions_count' => null,
                'remaining_sessions' => null,
                'how_know_us' => null,
                'payment_method_id' => 1,
                'status' => $subscriptionStatus,
                'notes' => $order->nots,
                'created_at' => now()->toDateTimeString(),
                'created_by' => 1,
            ];
            ++$newNumber;

            DB::table('subscriptions')->insert($subscriptionData);
        }
    }

    private function mapPlanType($days, $count): string
    {
        if (!empty($count) && $count > 0) {
            return 'sessions';
        }

        if ($days <= 1) return 'daily';
        if ($days <= 30) return 'monthly';
        if ($days <= 90) return 'quarterly';
        if ($days <= 365) return 'yearly';

        return 'monthly';
    }

    private function cleanNumber($value): array|string|null
    {
        if (!$value) return null;

        // شيل أي حاجة مش رقم
        $digits = preg_replace('/\D/', '', $value);

        // لو أقل من 10 أرقام أو كله أصفار → null
        if (strlen($digits) < 10 || preg_match('/^0+$/', $digits)) {
            return null;
        }

        return $digits;
    }

    function cleanHeight($value): ?float
    {
        if (!$value) return null;

        // استخرج أول رقم بس
        preg_match('/\d+(\.\d+)?/', $value, $matches);

        $height = isset($matches[0]) ? (float)$matches[0] : null;

        // validation منطقي
        if ($height < 50 || $height > 250) {
            return null;
        }

        return $height;
    }

    function cleanWeight($value): ?float
    {
        if (!$value) return null;

        preg_match('/\d+(\.\d+)?/', $value, $matches);

        $weight = isset($matches[0]) ? (float)$matches[0] : null;

        if ($weight < 20 || $weight > 300) {
            return null;
        }

        return $weight;
    }

    function parseDate($date): string
    {
        try {
            return Carbon::parse($date)->format('Y-m-d');
        } catch (\Exception $e) {
            return now()->format('Y-m-d');
        }
    }

    function safeDate($date): string
    {
        try {
            return Carbon::parse(trim($date))->format('Y-m-d H:i:s');
        } catch (\Exception $e) {
            return now()->format('Y-m-d H:i:s');
        }
    }


}
