<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Office;
use App\Models\User;
use App\Models\UserAuth;
use App\Models\RoleMaster;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Password;
use Illuminate\Support\Facades\Mail;
use App\Mail\WelcomeUserMail;
use App\Traits\ApiResponseTrait;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\DB;
use App\Models\UserDeleteLog;

class OfficeController extends Controller
{
    use ApiResponseTrait;

    /**
     * Generate branch or head office code
     */
    private function generateOfficeCode()
    {
        do {
            // Generate 5-character alphanumeric code
            $code = strtoupper(Str::random(5));

            // Check if already exists
            $exists = Office::where('office_code', $code)->exists();

        } while ($exists); // If exists → repeat

        return $code;
    }

    private function generateUserCode()
    {
        do {
            // Generate 5-character alphanumeric code
            $code = strtoupper(Str::random(5));

            // Check if already exists
            $exists = User::where('user_code', $code)->exists();

        } while ($exists); // If exists → repeat

        return $code;
    }

    /**
     * Create branch office, admin login & send email
     */
    public function createBranchOffice(Request $request)
    {
        $data = $request->validate([
            'name'           => 'required|string|max:200',
            'contact_person' => 'required|string|max:200',
            'email'          => 'required|email|unique:user_auth,email',
            'address'        => 'nullable|string|max:500',
            'phone'          => 'nullable|string|max:20',
            'mobile'         => 'nullable|string|max:20',
            'city_id'        => 'required|exists:city_master,id',
            'state_id'       => 'required|exists:state_master,id',
            'pincode'        => 'nullable|string|max:10',
        ]);


        DB::beginTransaction();

        try {
            // Create office
            $officeCode = $this->generateOfficeCode();
            $office = Office::create([
                'is_head_office' => 0,
                'office_code'    => $officeCode,
                'name'           => $data['name'],
                'email'        => $data['email'],
                'contact_person' => $data['contact_person'],
                'address'       => $data['address'],
                'phone'         => $data['phone'],
                'mobile'        => $data['mobile'],
                'city_id'        => $data['city_id'],
                'state_id'       => $data['state_id'],
                'pincode'        => $data['pincode'],
                'status'         => 1,
                'is_active'      => 1,
                'is_deleted'     => 0,
            ]);

            // Create Auth
             $plainPassword = Str::password(12);

            $auth = UserAuth::create([
                'email'     => $data['email'],
                'username'  => $data['email'],
                'password'  => Hash::make($plainPassword),
                'is_active' => 1,
            ]);



            $ip = $request->ip();
            $headersJson = json_encode($request->headers->all());
            $userCode = $this->generateUserCode();
            $adminUser = User::create([
                'user_auth_id' => $auth->id,
                'user_code'    => $userCode,
                'first_name'   => $data['contact_person'],
                'email'        => $data['email'],
                'office_id'    => $office->id,
                'role_id'      => 6,                                // Admin
                'user_type'    => 1,
                'is_active'    => 1,
                'headers'      => $data['headers'] ?? $headersJson,
                'register_ip'  => $data['register_ip'] ?? $ip,
            ]);

            // Create Token
            $token = Str::random(64);
            // Send Email
            Mail::to($data['email'])->send(new WelcomeUserMail($adminUser, $token));

            DB::commit();

            return $this->successResponse('Branch office created successfully');

        } catch (\Exception $e) {
            DB::rollBack();
            return $this->errorResponse('Failed to create branch office', $e->getMessage(), 500);
        }
    }

    /**
     * List all offices
     */
    public function listOffices()
    {
        $offices = Office::where('is_deleted', 0)
            ->with(['city_master', 'state_master', 'users','users.role'])
            ->orderBy('is_head_office', 'DESC')
            ->orderBy('name')
            ->get();

        return $this->successResponse('Office list fetched successfully', $offices);
    }

    public function getOffice($id)
    {
        $office = Office::where('id', $id)
            ->where('is_deleted', 0)
            ->with(['city_master', 'state_master'])
            ->first();

        return $office
            ? $this->successResponse('Office details fetched successfully', $office)
            : $this->errorResponse('Office not found', null, 404);
    }

    public function updateOffice(Request $request, $id)
    {
        $office = Office::where('id', $id)->where('is_deleted', 0)->first();

        if (!$office) {
            return $this->errorResponse('Office not found', null, 404);
        }

        $data = $request->validate([
            'name'     => 'required|string|max:200',
            'city_id'  => 'required|exists:city_master,id',
            'state_id' => 'required|exists:state_master,id',
            'pincode'  => 'required|string|max:10',
            'contact_person' => 'required|string|max:200',
            'address'        => 'required|string|max:500',
            'email'    => 'required|email',
            'phone'          => 'nullable|string|max:20',
            'mobile'         => 'nullable|string|max:20',
            'is_active'                 =>'required|integer',
        ]);

        $office->update($data);

        return $this->successResponse('Office updated successfully', $office);
    }

    public function deleteOffice(Request $request,$id)
    {
        $office = Office::where('id', $id)->where('is_deleted', 0)->first();

        if (!$office) {
            return $this->errorResponse('Office not found', null, 404);
        }

         if ($office->is_head_office == 1) {
            return $this->errorResponse('Head office cannot be deleted', null, 404);
        }

         UserDeleteLog::create( [
            'table_id' => $id,
            'table_name'  => 'office',
            'reason' => $request['reason'],
        ]);

        $office->update(['is_deleted' => 1]);

        return $this->successResponse('Office deleted successfully');
    }

}
