<?php

namespace App\Services;

use App\Models\User;
use App\Models\Batch;
use App\Models\PassingYear;
use App\Models\Alumni;
use App\Models\UserInstitution;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;

class SmsAlumniIngestService
{
    public function bulkUpsert(array $users): array
    {
        $tenantId = (int) config('sms.tenant_id', 1);

        $success = [];
        $failed  = [];

        try {
            DB::beginTransaction();

            foreach ($users as $row) {
                try {
                    $success[] = $this->upsertOne($tenantId, $row);
                } catch (\Throwable $e) {
                    $failed[] = [
                        'email' => $row['email'] ?? 'unknown',
                        'error' => $e->getMessage(),
                    ];
                }
            }

            // Match your legacy logic: rollback entire batch if ANY fail
            if (!empty($failed)) {
                DB::rollBack();
                return [
                    'success' => [],
                    'failed'  => array_map(function ($f) {
                        return [
                            'email' => $f['email'],
                            'error' => $f['error'] ?: 'Rolled back due to batch failure',
                        ];
                    }, $failed),
                    'rolled_back' => true,
                ];
            }

            DB::commit();

            return [
                'success' => $success,
                'failed'  => [],
                'rolled_back' => false,
            ];
        } catch (\Throwable $e) {
            DB::rollBack();
            throw $e;
        }
    }

    private function upsertOne(int $tenantId, array $data): array
    {
        // 1) USER: check exist by email, else create
        $user = User::where('tenant_id', $tenantId)
            ->where('email', $data['email'])
            ->first();

        if (!$user) {
            $fullName = trim(($data['firstname'] ?? '') . ' ' . ($data['lastname'] ?? ''));

            // Your old password logic: student_id@first3
            $rawPassword = ($data['student_id'] ?? '') . '@' . substr(($data['firstname'] ?? ''), 0, 3);

            $user = User::create([
                'tenant_id' => $tenantId,
                'name'      => $fullName !== '' ? $fullName : ($data['email']),
                'email'     => $data['email'],
                'mobile'    => $data['mobile'] ?? null,
                'password'  => Hash::make($rawPassword),
                'email_verified_at' => now(), // optional: depends on your flow
            ]);
        }

        // 2) BATCH: check by name (if provided)
        $batchId = null;
        if (!empty($data['batch'])) {
            $batch = Batch::firstOrCreate(
                ['tenant_id' => $tenantId, 'name' => $data['batch']],
                ['status' => 1]
            );
            $batchId = $batch->id;
        }

        // 3) PASSING YEAR: check by name/year (if provided)
        $passingYearId = null;
        if (!empty($data['passing_year'])) {
            $py = PassingYear::firstOrCreate(
                ['tenant_id' => $tenantId, 'name' => (string) $data['passing_year']],
                ['status' => 1]
            );
            $passingYearId = $py->id;
        }

        // 4) USER INSTITUTIONS: create/update (if you want only 1 row per user per tenant)
        // Adjust uniqueness rule if your design allows multiple institutions per user.
        UserInstitution::updateOrCreate(
            ['tenant_id' => $tenantId, 'user_id' => $user->id],
            [
                'degree'       => $data['degree'] ?? null,
                'programme_id' => $data['programme_id'] ?? null,
                'passing_year' => $data['passing_year'] ?? null,
            ]
        );

        // 5) ALUMNUS: upsert by tenant + student_id (or by tenant + user_id)
        $alumnus = Alumni::updateOrCreate(
            ['tenant_id' => $tenantId, 'id_number' => $data['student_id']],
            [
                'user_id'         => $user->id,
                'batch_id'        => $batchId,
                'passing_year_id' => $passingYearId,
                'date_of_birth'   => $data['birthdate'] ?? null,
                'gender'          => $data['gender'] ?? null,
                'city'            => $data['city'] ?? null,
                'state'           => $data['state'] ?? null,
                'zip'             => $data['zip'] ?? null,
                'country'         => $data['country'] ?? null,
                'country_id'      => $data['country_id'] ?? null,
                'address'         => $data['address'] ?? null,
            ]
        );

        return [
            'alumnus_id' => $alumnus->id,
            'user_id'    => $user->id,
            'email'      => $user->email,
        ];
    }
}
