<?php

namespace App\Service\User;

use App\Enum\UserType;
use App\Helpers\CodeGenerator;
use App\Helpers\MessageContent;
use App\Models\Admin;
use App\Models\User;
use App\Models\Vendor;
use App\Service\MailService;
use App\Traits\JsonResponseTrait;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;

class UserCreationService
{
    use JsonResponseTrait;

    /**
     * Create a user with optional profile
     */
    public function createUser(array $data)
    {
        DB::beginTransaction();

        try {
            // Create the user
            $user = User::create([
                'firstname' => $data['firstname'],
                'lastname' => $data['lastname'],
                'email' => strtolower(trim($data['email'])),
                'phone' => $data['phone'] ?? null,
                'password' => Hash::make($data['password']),
                'user_type' => $data['user_type'] ?? UserType::CUSTOMER->value,
                'status' => $data['status'] ?? 'active',
            ]);

            // Create profile based on user_type
            $profile = null;
            if ($user->user_type === UserType::ADMIN->value) {
                $profile = $this->createAdminProfile($user, $data);
            } elseif ($user->user_type === UserType::VENDOR->value) {
                $profile = $this->createVendorProfile($user, $data);
            }

            DB::commit();

            return $this->successDataResponse(
                data: [
                    'user' => $user,
                    'profile' => $profile,
                ],
                message: "User created successfully"
            );
        } catch (\Exception $e) {
            DB::rollBack();

            Log::error('User creation failed: ' . $e->getMessage(), [
                'email' => $data['email'] ?? null,
                'exception' => $e,
            ]);

            return $this->errorResponse(statusCode: 500, message: "An error occurred during user creation.");
        }
    }

    /**
     * Create admin profile for user
     */
    public function createAdminProfile(User $user, array $data)
    {
        return Admin::create([
            'user_id' => $user->id,
            'username' => $data['username'] ?? explode('@', $user->email)[0],
            'status' => $data['admin_status'] ?? 'active',
            'admin_level' => $data['admin_level'] ?? 1,
            'role' => $data['role'] ?? 'admin',
        ]);
    }

    /**
     * Create vendor profile for user
     */
    public function createVendorProfile(User $user, array $data)
    {
        return Vendor::create([
            'user_id' => $user->id,
            'business_name' => $data['business_name'] ?? $user->name,
            'email' => $data['business_email'] ?? $user->email,
            'phone' => $data['business_phone'] ?? $user->phone,
            'slug' => $data['slug'] ?? Str::slug($data['business_name'] ?? $user->name),
            'status' => $data['vendor_status'] ?? 'pending',
        ]);
    }

    /**
     * Create customer user (simple user creation)
     */
    public function createCustomer(array $data)
    {
        $data['user_type'] = 'customer';
        return $this->createUser($data);
    }

    /**
     * Create admin user with admin profile
     */
    public function createAdmin(array $data)
    {
        DB::beginTransaction();

        try {
            $data['user_type'] = UserType::ADMIN->value;

            // Generate random password for initial admin creation
            $tempPassword = $this->generateRandomPassword();
            $data['password'] = Hash::make($tempPassword);

            // Create user
            $user = User::create([
                'name' => $data['name'],
                'email' => strtolower(trim($data['email'])),
                'phone' => $data['phone'] ?? null,
                'password' => $data['password'],
                'user_type' => $data['user_type'],
                'status' => $data['status'] ?? 'active',
                'details_updated' => false, // Admin must update details after first login
            ]);

            // Create admin profile
            $admin = $this->createAdminProfile($user, $data);

            // Send login credentials via email
            $this->sendAdminCredentials($user, $tempPassword);

            DB::commit();

            return $this->successDataResponse(
                data: [
                    'user' => $user,
                    'admin' => $admin,
                    'message' => 'Admin created successfully. Login credentials sent to email.',
                ],
                message: "Admin created successfully"
            );
        } catch (\Exception $e) {
            DB::rollBack();

            Log::error('Admin creation failed: ' . $e->getMessage(), [
                'email' => $data['email'] ?? null,
                'exception' => $e,
            ]);

            return $this->errorResponse(statusCode: 500, message: "An error occurred during admin creation.");
        }
    }

    /**
     * Generate random temporary password
     */
    private function generateRandomPassword(): string
    {
        return strtoupper(substr(str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'), 0, 12));
    }

    /**
     * Send admin login credentials via email
     */
    private function sendAdminCredentials(User $user, string $tempPassword)
    {
        // TODO: Implement email service to send credentials
        // $this->mailService->sendEmail($user->email, 'Admin Account Created', [
        //     'name' => $user->name,
        //     'email' => $user->email,
        //     'temp_password' => $tempPassword,
        //     'login_url' => config('app.url') . '/admin/login',
        // ]);

        Log::info('Admin credentials sent', [
            'email' => $user->email,
            'temp_password' => $tempPassword,
        ]);
    }

    /**
     * Create vendor user with vendor profile
     */
    public function createVendor(array $data)
    {
        $data['user_type'] = UserType::VENDOR->value;
        return $this->createUser($data);
    }
}
