<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Helpers\TenantHelper;
use App\Models\Admin_User;
use App\Models\MerchantEmployee;
use App\Models\VendorUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
use Illuminate\Validation\Rule;
use Barryvdh\DomPDF\Facade\Pdf;

class MerchantEmployeeController extends Controller
{
    // All actions are scoped to current merchant via user's vendor UUID helper

    protected function currentMerchantUuid(Request $request): ?string
    {
        $vendorUser = VendorUsers::where('user_id', Auth::guard('admin')->id())->first();
        return $vendorUser?->uuid ?? null;
    }

    public function index(Request $request)
    {
        $merchantUuid = $this->currentMerchantUuid($request);
        abort_if(!$merchantUuid, 403);
        // if (!$merchantUuid) {
        //     dd('Condition failed', $merchantUuid, $request->all());
        // }

        // Ensure a MAIN user exists for this merchant (owner of current restaurant)
        // Determine vendor owner from vendor_users with roleType = 'vendor'
        $vendorOwner = DB::table('vendor_users')
            ->where('uuid', $merchantUuid)
            ->where('roleType', 'vendor')
            ->orderBy('user_id')
            ->first();

        $hasMain = MerchantEmployee::where('merchant_uuid', $merchantUuid)
            ->where('is_main_user', true)
            ->exists();
        if (!$hasMain && $vendorOwner) {
            $ownerUser = Admin_User::find($vendorOwner->user_id);
            if ($ownerUser) {
                // Ensure link exists (should already)
                $linkExists = DB::table('vendor_users')
                    ->where('user_id', $ownerUser->id)
                    ->where('uuid', $merchantUuid)
                    ->exists();
                if (!$linkExists) {
                    $payload = [
                        'user_id' => $ownerUser->id,
                        'uuid' => $merchantUuid,
                        'email' => $ownerUser->email,
                        'roleType' => 'vendor',
                    ];
                    try {
                        DB::table('vendor_users')->insert($payload);
                    } catch (\Throwable $e) {
                        $payload['id'] = $ownerUser->id;
                        DB::table('vendor_users')->insert($payload);
                    }
                }

                $first = $ownerUser->name;
                $last = '';
                if (str_contains($ownerUser->name ?? '', ' ')) {
                    $parts = preg_split('/\s+/', trim((string) $ownerUser->name), 2);
                    $first = $parts[0] ?? '';
                    $last = $parts[1] ?? '';
                }

                MerchantEmployee::create([
                    'merchant_uuid' => $merchantUuid,
                    'user_id' => $ownerUser->id,
                    'name' => $first,
                    'surname' => $last,
                    'email' => $ownerUser->email,
                    'role' => 'main_user',
                    'status' => 'aktywny',
                    'is_main_user' => true,
                    'permissions' => ['home', 'orders', 'live_orders', 'menu', 'restaurant', 'account', 'manage_users'],
                ]);
            }
        }

        $employees = MerchantEmployee::where('merchant_uuid', $merchantUuid)
            ->orderByDesc('is_main_user')
            ->orderBy('id')
            ->get();

        return response()->json($employees);
    }

    public function store(Request $request)
    {
        $merchantUuid = $this->currentMerchantUuid($request);
        abort_if(!$merchantUuid, 403);
        // if (!$merchantUuid) {
        //     dd('Condition failed', $merchantUuid, $request->all());
        // }

        $validated = $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'surname' => ['required', 'string', 'max:255'],
            'email' => ['required', 'email', 'max:255', Rule::unique('merchant_employees', 'email')->where(fn($q) => $q->where('merchant_uuid', $merchantUuid))],
            'password' => ['required', 'string', 'min:8'],
            'role' => ['required', 'string', 'max:255'],
            'status' => ['required', Rule::in(['aktywny', 'nieaktywny'])],
            'permissions' => ['array'],
            'send_welcome_email' => ['sometimes', 'boolean'],
        ]);

        return DB::transaction(function () use ($validated, $merchantUuid) {
            // Create user if not existing by email
            $existingUser = Admin_User::where('email', $validated['email'])->first();
            \Log::info('Creating user - existing check', [
                'email' => $validated['email'],
                'user_exists' => !!$existingUser,
                'will_update_password' => !!$existingUser
            ]);

            if ($existingUser) {
                // Jeśli użytkownik istnieje, zaktualizuj hasło
                $existingUser->password = Hash::make($validated['password']);
                $existingUser->save();
                $user = $existingUser;
                \Log::info('Updated existing user password', ['user_id' => $user->id]);
            } else {
                // Utwórz nowego użytkownika
                $user = Admin_User::create([
                    'name' => $validated['name'] . ' ' . $validated['surname'],
                    'email' => $validated['email'],
                    'password' => Hash::make($validated['password']),
                ]);
                \Log::info('Created new user', ['user_id' => $user->id]);
            }

            // Ensure vendor_users linkage exists for login scoped to merchant
            $existsLink = DB::table('vendor_users')
                ->where('user_id', $user->id)
                ->where('uuid', $merchantUuid)
                ->exists();
            if (!$existsLink) {
                $payload = [
                    'user_id'  => $user->id,
                    'uuid'     => $merchantUuid,
                    'email'    => $validated['email'],
                    'roleType' => 'employee',
                ];
                try {
                    DB::table('vendor_users')->insert($payload);
                } catch (\Throwable $e) {
                    $payload['id'] = $user->id;
                    DB::table('vendor_users')->insert($payload);
                }
            }

            $employee = MerchantEmployee::create([
                'merchant_uuid' => $merchantUuid,
                'user_id' => $user->id,
                'name' => $validated['name'],
                'surname' => $validated['surname'],
                'email' => $validated['email'],
                'role' => $validated['role'],
                'status' => $validated['status'],
                'is_main_user' => false,
                'permissions' => $validated['permissions'] ?? [],
            ]);

            // Send welcome email with temporary password if requested
            if (!empty($validated['send_welcome_email'])) {
                try {
                    // Get restaurant name from Firebase
                    $restaurantName = $this->getRestaurantNameFromFirebase($merchantUuid);

                    Mail::to($validated['email'])->send(new \App\Mail\EmployeeWelcomeMail(
                        name: $validated['name'] . ' ' . $validated['surname'],
                        email: $validated['email'],
                        password: $validated['password'],
                        restaurantName: $restaurantName,
                        position: $validated['role']
                    ));
                } catch (\Throwable $e) {
                    // Non-fatal: log and continue
                    \Log::warning('Failed sending welcome email', ['error' => $e->getMessage()]);
                }
            }

            // Firebase sync temporarily disabled - users will be created via Web SDK during first login
            \Log::info('User created in MySQL, Firebase sync skipped', [
                'user_id' => $user->id,
                'email' => $validated['email'],
                'merchant_uuid' => $merchantUuid
            ]);

            // Never return password
            return response()->json($employee, 201);
        });
    }

    public function update(Request $request, MerchantEmployee $merchantEmployee)
    {
        $merchantUuid = $this->currentMerchantUuid($request);
        abort_if(!$merchantUuid || $merchantEmployee->merchant_uuid !== $merchantUuid, 403);
        abort_if($merchantEmployee->is_main_user, 403, 'Main user cannot be modified');

        $validated = $request->validate([
            'name' => ['sometimes', 'required', 'string', 'max:255'],
            'surname' => ['sometimes', 'required', 'string', 'max:255'],
            'role' => ['sometimes', 'required', 'string', 'max:255'],
            'status' => ['sometimes', 'required', Rule::in(['aktywny', 'nieaktywny'])],
            'email' => ['prohibited'], // immutable; aligns with UI
            'password' => ['nullable', 'string', 'min:8'],
        ]);

        return DB::transaction(function () use ($validated, $merchantEmployee, $request) {
            if (array_key_exists('password', $validated) && $validated['password']) {
                // Update auth user password if employees share same login table
                $user = $merchantEmployee->user;
                if ($user) {
                    $user->password = Hash::make($validated['password']);
                    $user->save();
                }
                // Sync also to Firebase Auth (non-fatal)
                // Firebase password sync temporarily disabled
                \Log::info('Password updated in MySQL, Firebase sync skipped', [
                    'employee_id' => $merchantEmployee->id,
                    'email' => $merchantEmployee->email
                ]);
            }

            unset($validated['password']);
            $merchantEmployee->fill($validated);
            $merchantEmployee->save();
            return response()->json($merchantEmployee);
        });
    }

    public function destroy(Request $request, MerchantEmployee $merchantEmployee)
    {
        $merchantUuid = $this->currentMerchantUuid($request);
        abort_if(!$merchantUuid || $merchantEmployee->merchant_uuid !== $merchantUuid, 403);
        abort_if($merchantEmployee->is_main_user, 403, 'Main user cannot be deleted');

        // Remove membership link from vendor_users for this merchant
        $userId = $merchantEmployee->user_id;
        DB::table('vendor_users')
            ->where('user_id', $userId)
            ->where('uuid', $merchantUuid)
            ->delete();

        // Delete employee profile: hard delete to keep DB consistent
        try {
            if (method_exists($merchantEmployee, 'forceDelete')) {
                $merchantEmployee->forceDelete();
            } else {
                $merchantEmployee->delete();
            }
        } catch (\Throwable $e) {
            \Log::warning('Failed deleting merchant employee', ['id' => $merchantEmployee->id, 'error' => $e->getMessage()]);
        }

        // Firebase cleanup temporarily disabled - users remain in Firebase
            $remaining = DB::table('vendor_users')->where('user_id', $userId)->count();
            if ($remaining === 0) {
            // Remove from Laravel users table as no other memberships remain
            try {
                \App\Models\Admin_User::where('id', $userId)->delete();
                \Log::info('User deleted from MySQL, Firebase cleanup skipped', [
                    'user_id' => $userId,
                    'email' => $merchantEmployee->email
                ]);
            } catch (\Throwable $e) {
                \Log::warning('Failed to delete user from MySQL', ['user_id' => $userId, 'error' => $e->getMessage()]);
            }
        }

        return response()->json(['success' => true]);
    }

    public function updatePermissions(Request $request, MerchantEmployee $merchantEmployee)
    {
        $merchantUuid = $this->currentMerchantUuid($request);
        abort_if(!$merchantUuid || $merchantEmployee->merchant_uuid !== $merchantUuid, 403);
        abort_if($merchantEmployee->is_main_user, 403, 'Main user permissions are fixed');

        $validated = $request->validate([
            'permissions' => ['required', 'array'],
        ]);

        // Always ensure 'account' permission is present
        $permissions = array_values(array_unique(array_merge(['account'], $validated['permissions'])));
        $merchantEmployee->permissions = $permissions;
        $merchantEmployee->save();

        return response()->json($merchantEmployee);
    }

    public function syncFirebase(Request $request, MerchantEmployee $merchantEmployee)
    {
        $merchantUuid = $this->currentMerchantUuid($request);
        abort_if(!$merchantUuid || $merchantEmployee->merchant_uuid !== $merchantUuid, 403);

        $validated = $request->validate([
            'password' => ['required', 'string', 'min:8'],
        ]);

        // Firebase sync temporarily disabled - Admin SDK not configured
        \Log::info('Firebase sync skipped - Admin SDK not available', [
            'employee_id' => $merchantEmployee->id,
            'email' => $merchantEmployee->email
        ]);
        return response()->json(['success' => true, 'message' => 'Firebase sync disabled']);
    }

    public function updateProfile(Request $request)
    {
        $user = Auth::user();
        $merchantEmployee = MerchantEmployee::where('user_id', $user->id)->first();

        if (!$merchantEmployee) {
            return response()->json(['error' => 'Employee record not found'], 404);
        }

        $request->validate([
            'firstName' => 'required|string|max:255',
            'lastName' => 'required|string|max:255',
            'phone' => 'nullable|string|max:20',
        ]);

        try {
            $merchantEmployee->update([
                'name' => $request->firstName,
                'surname' => $request->lastName,
                'phone' => $request->phone,
            ]);

            return response()->json([
                'success' => true,
                'message' => 'Profile updated successfully',
                'data' => [
                    'firstName' => $merchantEmployee->name,
                    'lastName' => $merchantEmployee->surname,
                    'email' => $merchantEmployee->email,
                ]
            ]);
        } catch (\Exception $e) {
            \Log::error('Employee profile update failed', ['error' => $e->getMessage(), 'user_id' => $user->id]);
            return response()->json(['error' => 'Failed to update profile'], 500);
        }
    }

    public function changePassword(Request $request)
    {
        $user = Auth::user();
        $merchantEmployee = MerchantEmployee::where('user_id', $user->id)->first();

        if (!$merchantEmployee) {
            return response()->json(['error' => 'Employee record not found'], 404);
        }

        $request->validate([
            'old_password' => 'required|string',
            'new_password' => 'required|string|min:8',
        ]);

        try {
            // Sprawdź czy stare hasło jest poprawne
            if (!Hash::check($request->old_password, $user->password)) {
                return response()->json(['error' => 'Old password is incorrect'], 400);
            }

            // Zaktualizuj hasło
            $user->password = Hash::make($request->new_password);
            $user->save();

            \Log::info('Employee password changed successfully', [
                'employee_id' => $merchantEmployee->id,
                'email' => $merchantEmployee->email
            ]);

            return response()->json([
                'success' => true,
                'message' => 'Password changed successfully'
            ]);
        } catch (\Exception $e) {
            \Log::error('Employee password change failed', [
                'error' => $e->getMessage(),
                'user_id' => $user->id
            ]);
            return response()->json(['error' => 'Failed to change password'], 500);
        }
    }

    public function cleanPhoneData(Request $request)
    {
        $user = Auth::user();
        $merchantEmployee = MerchantEmployee::where('user_id', $user->id)->first();

        if (!$merchantEmployee) {
            return response()->json(['error' => 'Employee record not found'], 404);
        }

        // Wyczyść pole phone jeśli zawiera email
        if ($merchantEmployee->phone && str_contains($merchantEmployee->phone, '@')) {
            $oldPhone = $merchantEmployee->phone;
            $merchantEmployee->update(['phone' => null]);

            return response()->json([
                'success' => true,
                'message' => 'Phone field cleaned',
                'old_value' => $oldPhone,
                'new_value' => null
            ]);
        }

        return response()->json([
            'success' => true,
            'message' => 'Phone field is already clean',
            'current_value' => $merchantEmployee->phone
        ]);
    }

    public function uploadProfilePicture(Request $request)
    {
        $user = Auth::user();
        $merchantEmployee = MerchantEmployee::where('user_id', $user->id)->first();

        if (!$merchantEmployee) {
            return response()->json(['error' => 'Employee record not found'], 404);
        }

        $request->validate([
            'profile_picture' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048', // 2MB max
        ]);

        try {
            \Log::info('Profile picture upload attempt', [
                'employee_id' => $merchantEmployee->id,
                'has_file' => $request->hasFile('profile_picture'),
                'files' => array_keys($request->allFiles())
            ]);

            if ($request->hasFile('profile_picture')) {
                $file = $request->file('profile_picture');

                \Log::info('File details', [
                    'original_name' => $file->getClientOriginalName(),
                    'size' => $file->getSize(),
                    'mime_type' => $file->getMimeType(),
                    'is_valid' => $file->isValid()
                ]);

                // Generate unique filename
                $extension = $file->getClientOriginalExtension() ?: 'jpg'; // fallback to jpg if no extension
                $filename = 'employee_' . $merchantEmployee->id . '_' . time() . '.' . $extension;

                \Log::info('Generated filename', ['filename' => $filename]);

                // Store directly in public/images/employees directory (bez storage symlink)
                $publicPath = public_path('images/employees');
                if (!file_exists($publicPath)) {
                    mkdir($publicPath, 0755, true);
                }

                $fullPath = $publicPath . '/' . $filename;
                $file->move($publicPath, $filename);
                \Log::info('File stored directly in public', ['full_path' => $fullPath]);

                // Delete old profile picture if exists
                if ($merchantEmployee->profile_picture) {
                    $oldPath = public_path(ltrim($merchantEmployee->profile_picture, '/'));
                    if (file_exists($oldPath)) {
                        unlink($oldPath);
                        \Log::info('Deleted old profile picture', ['old_path' => $oldPath]);
                    }
                }

                // Update database with new path (bez /storage/)
                $profilePictureUrl = '/images/employees/' . $filename;
                $merchantEmployee->update(['profile_picture' => $profilePictureUrl]);

                return response()->json([
                    'success' => true,
                    'message' => 'Profile picture uploaded successfully',
                    'profile_picture_url' => $profilePictureUrl
                ]);
            }

            return response()->json(['error' => 'No file uploaded'], 400);
        } catch (\Exception $e) {
            \Log::error('Employee profile picture upload failed', ['error' => $e->getMessage(), 'user_id' => $user->id]);
            return response()->json(['error' => 'Failed to upload profile picture'], 500);
        }
    }

    /**
     * Get restaurant name from PostgreSQL tenant schema.
     */
    private function getRestaurantNameFromFirebase(string $merchantUuid): string
    {
        try {
            $vendorUser = VendorUsers::where('uuid', $merchantUuid)
                ->where('roleType', 'vendor')
                ->first();

            if ($vendorUser && $vendorUser->schema_name) {
                \App\Helpers\TenantHelper::setSchema($vendorUser->schema_name);
                $vendor = DB::connection('pgsql_country')
                    ->table('vendors')
                    ->where('owner_id', $vendorUser->user_id)
                    ->value('title');

                if ($vendor) {
                    return $vendor;
                }
            }
        } catch (\Exception $e) {
            \Log::warning('Failed to fetch restaurant name from DB', [
                'error' => $e->getMessage(),
                'merchantUuid' => $merchantUuid,
            ]);
        }

        return 'Restauracja';
    }

    /**
     * Get QR code for employee
     */
    public function getQrCode(Request $request, MerchantEmployee $merchantEmployee)
    {
        $merchantUuid = $this->currentMerchantUuid($request);
        abort_if(!$merchantUuid || $merchantEmployee->merchant_uuid !== $merchantUuid, 403);

        if (!$merchantEmployee->pin || !$merchantEmployee->qr_code_key) {
            return response()->json([
                'error' => 'Employee does not have a PIN set'
            ], 400);
        }

        $qrCodeService = new QrCodeService();
        $qrCodeImage = $qrCodeService->generateQrCodeImage($merchantEmployee->user_id);

        return response()->json([
            'qr_code' => $qrCodeImage,
            'employee' => [
                'name' => $merchantEmployee->name . ' ' . $merchantEmployee->surname,
                'role' => $merchantEmployee->role,
                'email' => $merchantEmployee->email,
            ]
        ]);
    }

    /**
     * Generate printable QR card PDF
     */
    public function generateQrCardPdf(Request $request, MerchantEmployee $merchantEmployee)
    {
        $merchantUuid = $this->currentMerchantUuid($request);
        abort_if(!$merchantUuid || $merchantEmployee->merchant_uuid !== $merchantUuid, 403);

        if (!$merchantEmployee->pin || !$merchantEmployee->qr_code_key) {
            return response()->json([
                'error' => 'Employee does not have a PIN set'
            ], 400);
        }

        $qrCodeService = new QrCodeService();
        $qrCodeImage = $qrCodeService->generateQrCodePng($merchantEmployee->user_id);

        // Get restaurant name
        $restaurantName = $this->getRestaurantNameFromFirebase($merchantUuid);

        $data = [
            'employee' => $merchantEmployee,
            'qr_code' => $qrCodeImage,
            'restaurant_name' => $restaurantName,
        ];

        $pdf = Pdf::loadView('pdf.qr-card', $data)
            ->setPaper([0, 0, 242.65, 153.07], 'landscape'); // ID card size in points (85.6mm x 53.98mm)

        return $pdf->stream('qr-card-' . $merchantEmployee->name . '-' . $merchantEmployee->surname . '.pdf');
    }
}


