<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\DB;
use libphonenumber\PhoneNumberUtil;
use libphonenumber\PhoneNumberFormat;

class ApiController extends Controller
{
    /**
     * Find a user by ID
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function find_user(Request $request)
    {
        // 1. Get the token from the request header (Key should be 'token')
        $token = $request->header('token');

        // 2. Verify the token 
        $SECRET_TOKEN = "8f4d9b2e1a3c7f605d8e2b9c4a1f3b7d";
        if ($token !== $SECRET_TOKEN) {
            return response()->json([
                'status' => 'error',
                'message' => 'Unauthorized: Invalid token'
            ], 401);
        }

        $email = !empty($request->email) ? $request->email : 'null';
        $phone = !empty($request->phone_number) ? $request->phone_number : 'null';

        if ($email == 'null' && $phone == 'null') {
            return response()->json([
                'status' => '0',
                'message' => 'User not found',
            ], 200);
        }

        $formattedPhone = $phone;

        if (!empty($phone)) {
            try {
                $phoneUtil = PhoneNumberUtil::getInstance();
                $numberProto = $phoneUtil->parse($phone, null);
                $countryCode = $numberProto->getCountryCode();
                $nationalNumber = $numberProto->getNationalNumber();
                $formattedPhone = '+' . $countryCode . '-' . $nationalNumber;
            } catch (\Exception $e) {
                $formattedPhone = $phone;
            }
        }

        $site_sort_name = !empty($request->site_sort_name) ? $request->site_sort_name : $this->getSiteSortNameByNumber($request->whatsapp_number);

        // Check if user exists in 'users' table (mapped to Customer model)
        $user = \App\Models\Customer::select('cust_name as name', 'email', 'phone as phone_number', 'web_sort_name', 'lead_source')
            ->when($site_sort_name, function ($q) use ($site_sort_name) {
                return $q->where('web_sort_name', $site_sort_name);
            })
            ->where('phone', '!=', '')
            ->where(function ($query) use ($phone, $formattedPhone) {
                if (!empty($phone)) {
                    $query->where('phone', $phone)
                        ->orWhere('phone', $formattedPhone);
                }
            })
            ->orderBy('id', 'desc')->first();

        if ($user) {
            return response()->json([
                'status' => '1',
                'message' => 'User found successfully',
                'data' => $user
            ], 200);
        }

        // Create new user if not found
        $countryName = '';
        if (isset($countryCode)) {
            $countryName = \Illuminate\Support\Facades\DB::table('country')
                ->where('code', $countryCode)
                ->value('name') ?? '';
        }

        $password = md5('user123');
        $ipAddress = $_SERVER['REMOTE_ADDR'] ?? '';

        $newCustomer = \App\Models\Customer::create([
            'cust_name' => $request->name ?? 'New Customer',
            'password' => $password,
            'email' => ($email !== 'null') ? $email : '',
            'status' => 1,
            'phone' => ($phone !== 'null') ? $formattedPhone : '',
            'country' => $countryName ?: ($request->country ?? ''),
            'customer_password_md5_decode' => 'user123',
            'lead_source' => 'Whatsapp',
            'web_sort_name' => $site_sort_name ?? 'GAH',
            'BD_name' => '',
            'promotion_status' => 0,
            'activate' => 0,
            'storecredit' => 0,
            'image' => '',
            'city' => '',
            'address' => '',
            'link' => '',
            'verify' => 0,
            'view' => 0,
            'rwards_point' => 0,
            'online' => 0,
            'ip_address' => $ipAddress,
            'customer_type' => 0,
            'vendor_view' => 0,
            'vendor_cust_deleted_status' => 0,
            'customer_from' => 0,
            'other_info' => '',
            'auto_mail_send' => 0,
            'payment_getway_token' => '',
            'alternate_phone' => '',
            'alternate_email' => '',
            'email_verify' => 0,
            'phone_verify' => 0,
            'assign_to' => 0,
            'refered_by' => 0,
            'whatsapp_status' => 0,
            'qualification' => '',
            'college' => '',
            'coupon' => '',
            'course' => '',
            'zendesk_ticket_id' => 0,
            'stage' => 'Enquiry',
        ]);

        if (class_exists('\App\Models\UserLog')) {
            try {
                \App\Models\UserLog::create([
                    'user_id' => $newCustomer->id,
                    'old_event' => 'Enquiry',
                    'event_type' => 'Stage',
                    'changed_by' => 1,
                    'changed_at' => now()
                ]);
            } catch (\Throwable $e) {
                \Illuminate\Support\Facades\Log::warning('UserLog create error: ' . $e->getMessage());
            }
        }

        $user = \App\Models\Customer::select('cust_name as name', 'email', 'phone as phone_number', 'web_sort_name', 'lead_source')
            ->where('id', $newCustomer->id)
            ->first();

        return response()->json([
            'status' => '0',
            'message' => 'User created successfully',
            'data' => $user
        ], 200);
    }

    public function get_order_details(Request $request)
    {
        // Require the static token for authentication
        $token = $request->header('token');
        if ($token !== '1e4e20745582f33c8733ea71f54cf21e') {
            return response()->json([
                'status' => '0',
                'message' => 'Unauthorized'
            ], 401);
        }

        $order_code = $request->input('order_code');

        if (empty($order_code)) {
            return response()->json([
                'status' => '0',
                'message' => 'order_code parameter is required'
            ], 200);
        }

        $order = \App\Models\Order::where(function ($query) use ($order_code) {
            $query->where('order_code', $order_code)
                ->orWhere('id', $order_code);
        })
            ->where('project_status', '!=', 'Not Accepted')
            ->where('internal_pro_status', '!=', 'Cancelled')
            ->first();

        if ($order) {
            if (strtolower($order->internal_pro_status) === 'clarification') {
                $last_chat = \Illuminate\Support\Facades\DB::table('tb_chat')
                    ->where('ordercode', $order->order_code)
                    ->orderBy('id', 'desc')
                    ->first();
                $order->clarification_message = $last_chat ? $last_chat->message : null;
            }

            // Create dashboard links
            $websiteUrl = [
                'GAH' => "https://www.globalassignmenthelp.com/",
                'IAH' => "https://www.instantassignmenthelp.com/",
                'IAH_AU' => "https://www.instantassignmenthelp.com.au/",
                'GAH_AU' => "https://au1.globalassignmenthelp.com.au/",
                'AP' => "https://www.assignmentprime.com/",
                'AD' => "https://www.assignmentdesk.co.uk/"
            ];
            $webName = $order->site_sort_name;
            $id = $order->cust_id;

            $token = '';
            if (!empty($id)) {
                $token = base64_encode(base64_encode($webName . '?$&@' . $id));
            }

            $order->dashboard_link = ($websiteUrl[$webName] ?? '') . 'whatsaap.php?id=' . $token;

            $website_raw_login_links = [
                'GAH' => 'https://www.globalassignmenthelp.com/login',
                'IAH' => 'https://www.instantassignmenthelp.com/login',
                'AD' => 'https://www.assignmentdesk.co.uk/login',
                'AP' => 'https://www.assignmentprime.com/login',
                'IAH_AU' => 'https://www.instantassignmenthelp.com.au/login',
                'GAH_AU' => 'https://www.globalassignmenthelp.com.au/login'
            ];
            $order->login_link = $website_raw_login_links[$order->site_sort_name] ?? null;

            // Deadline Breach Check
            $allowed_statuses = ['tba', 'team allotted', 'in process', 'clarification resolved', 're-do', 'feedback'];
            if (in_array(strtolower($order->internal_pro_status), $allowed_statuses)) {
                $slices = \Illuminate\Support\Facades\DB::table('delivery_slice')
                    ->where('order_id', $order->id)
                    ->get();
                $slice_count = $slices->count();

                if ($slice_count > 1) {
                    $order->deadline_breach_status = 'Multiple Slices';
                } elseif ($slice_count === 1) {
                    $slice = $slices->first();
                    $delivery_date = \Carbon\Carbon::parse($slice->delivery_date);
                    if ($delivery_date->isPast()) {
                        $order->deadline_breach_status = 'Deadline Breached';
                    } else {
                        $order->deadline_breach_status = 'Deadline Upcoming';
                    }
                } else {
                    $datetime = $order->ddate . ' ' . (!empty($order->dtime) ? $order->dtime : '00:00:00');
                    $delivery_date = \Carbon\Carbon::parse($datetime);
                    if ($delivery_date->isPast()) {
                        $order->deadline_breach_status = 'Deadline Breached';
                    } else {
                        $order->deadline_breach_status = 'Deadline Upcoming';
                    }
                }
            }

            if (!empty($order->ddate)) {
                $order->formatted_ddate = \Carbon\Carbon::parse($order->ddate)->format('d-m-Y');
            }

            if ($order->pay_status == 'Partially paid') {
                if (!empty($order->payment_source)) {
                    switch ($order->payment_source) {
                        case 35:
                            $order->bank_details = "Cognus Technology UK Limited\nAcc Number - 00026884\nSORT Code - 77-91-21\nReference - " . $order->order_code;
                            break;
                        case 20:
                            $order->bank_details = "Bank Name- Barclays Bank PLC\nCompany / Payee Name- Optiweb Solutions Ltd\nAccount Number- 43793958\nSort Code - 20 92 63\nSwift Code - BARCGB22\nReference - " . $order->order_code;
                            break;
                        case 27:
                            $order->bank_details = "VERTELIO FINVEST PRIVATE LIMITED\nacc no-004505009256\nIFSC CODE-ICIC0000045\nReference - " . $order->order_code;
                            break;
                        default:
                            $order->bank_details = $order->dashboard_link ?? null;
                            break;
                    }
                }
            }
            $response = [
                'status' => '1',
                'message' => 'Order details found successfully',
                'data' => $order
            ];

            $phone_number = $request->input('phone_number');
            if (!empty($phone_number)) {
                $formattedPhone = $phone_number;
                try {
                    $phoneUtil = PhoneNumberUtil::getInstance();
                    $numberProto = $phoneUtil->parse($phone_number, null);
                    $countryCode = $numberProto->getCountryCode();
                    $nationalNumber = $numberProto->getNationalNumber();
                    $formattedPhone = '+' . $countryCode . '-' . $nationalNumber;
                } catch (\Exception $e) {
                    $formattedPhone = $phone_number;
                }

                $customer = \App\Models\Customer::find($order->cust_id);
                $order_phone = $customer ? $customer->phone : $order->customer_phone;

                if ($order_phone !== $phone_number && $order_phone !== $formattedPhone) {
                    $response['order_not_found'] = 1;
                } else {
                    $response['order_not_found'] = 0;
                }
            }

            return response()->json($response, 200);
        }

        return response()->json([
            'status' => '0',
            'message' => 'Order not found',
        ], 200);
    }

    public function get_client_orders(Request $request)
    {
        // 1. Get the token from the request header (Key should be 'token')
        $token = $request->header('token');

        // 2. Verify the token 
        $SECRET_TOKEN = "8f4d9b2e1a3c7f605d8e2b9c4a1f3b7d";
        if ($token !== $SECRET_TOKEN) {
            return response()->json([
                'status' => 'error',
                'message' => 'Unauthorized: Invalid token'
            ], 401);
        }

        $email = ($request->email === 'null' || empty($request->email)) ? null : trim($request->email);
        $phoneInput = $request->phone_number ?? $request->phone;
        $phone = ($phoneInput === 'null' || empty($phoneInput)) ? null : trim($phoneInput);

        // If both are empty, return error
        if (empty($email) && empty($phone)) {
            return response()->json([
                'status' => '0',
                'message' => 'Email or Phone Number is required',
            ], 200);
        }

        $phoneVariations = [];
        $nationalNumber = null;

        if (!empty($phone)) {
            $phoneVariations[] = $phone;

            // Handle cases where '+' was decoded as space
            if (strpos($phone, ' ') === 0) {
                $phoneWithPlus = '+' . ltrim($phone);
                $phoneVariations[] = $phoneWithPlus;
                $phone = $phoneWithPlus;
            }

            $cleanPhone = preg_replace('/[^\d+]/', '', $phone);
            if (!empty($cleanPhone)) {
                $phoneVariations[] = $cleanPhone;
            }

            try {
                $phoneUtil = PhoneNumberUtil::getInstance();
                $numberProto = $phoneUtil->parse($phone, null);
                $countryCode = $numberProto->getCountryCode();
                $nationalNumber = (string) $numberProto->getNationalNumber();

                $phoneVariations[] = '+' . $countryCode . '-' . $nationalNumber;
                $phoneVariations[] = '+' . $countryCode . $nationalNumber;
                $phoneVariations[] = $nationalNumber;
            } catch (\Exception $e) {
                $digits = preg_replace('/\D/', '', $phone);
                if (strlen($digits) >= 7) {
                    $nationalNumber = substr($digits, -10);
                }
            }

            $phoneVariations = array_values(array_unique(array_filter($phoneVariations)));
        }

        $site_sort_name = !empty($request->site_sort_name) ? $request->site_sort_name : $this->getSiteSortNameByNumber($request->whatsapp_number);

        // Query all matching customer IDs
        $customerQuery = \App\Models\Customer::where(function ($query) use ($phoneVariations, $nationalNumber, $email) {
            $hasCondition = false;
            if (!empty($phoneVariations)) {
                $query->where(function ($q) use ($phoneVariations, $nationalNumber) {
                    $q->whereIn('phone', $phoneVariations);
                    if (!empty($nationalNumber)) {
                        $q->orWhere('phone', 'like', '%' . $nationalNumber . '%');
                    }
                });
                $hasCondition = true;
            }
            if (!empty($email)) {
                if ($hasCondition) {
                    $query->orWhere('email', $email);
                } else {
                    $query->where('email', $email);
                }
            }
        });

        if (!empty($site_sort_name)) {
            $customerQuery->where('web_sort_name', $site_sort_name);
        }

        $customerIds = $customerQuery->pluck('id')->toArray();

        // Query orders linked either via cust_id, customer_phone, or customer_email
        $orderQuery = \App\Models\Order::whereNotNull('order_code')
            ->where('order_code', '!=', '')
            ->where('project_status', '!=', 'Not Accepted')
            ->where('internal_pro_status', '!=', 'Cancelled')
            ->where(function ($query) use ($customerIds, $phoneVariations, $nationalNumber, $email) {
                $hasCondition = false;
                if (!empty($customerIds)) {
                    $query->whereIn('cust_id', $customerIds);
                    $hasCondition = true;
                }
                if (!empty($phoneVariations)) {
                    $method = $hasCondition ? 'orWhere' : 'where';
                    $query->$method(function ($q) use ($phoneVariations, $nationalNumber) {
                        $q->whereIn('customer_phone', $phoneVariations);
                        if (!empty($nationalNumber)) {
                            $q->orWhere('customer_phone', 'like', '%' . $nationalNumber . '%');
                        }
                    });
                    $hasCondition = true;
                }
                if (!empty($email)) {
                    $method = $hasCondition ? 'orWhere' : 'where';
                    $query->$method('customer_email', $email);
                }
            });

        if (!empty($site_sort_name)) {
            $orderQuery->where('site_sort_name', $site_sort_name);
        }

        $orders = $orderQuery->orderBy('id', 'desc')
            ->pluck('order_code')
            ->unique()
            ->filter()
            ->values();

        if ($orders->isNotEmpty()) {
            return response()->json([
                'status' => '1',
                'message' => 'Orders retrieved successfully',
                'data' => $orders->implode("\n")
            ], 200);
        }

        if (empty($customerIds)) {
            return response()->json([
                'status' => '0',
                'message' => 'User not found',
            ], 200);
        }

        return response()->json([
            'status' => '0',
            'message' => 'No orders found',
            'data' => ''
        ], 200);
    }

    public function get_pending_payments_orders(Request $request)
    {
        $token = $request->header('token');
        $SECRET_TOKEN = "8f4d9b2e1a3c7f605d8e2b9c4a1f3b7d";
        if ($token !== $SECRET_TOKEN) {
            return response()->json([
                'status' => 'error',
                'message' => 'Unauthorized: Invalid token'
            ], 401);
        }

        $email = ($request->email === 'null' || empty($request->email)) ? null : trim($request->email);
        $phoneInput = $request->phone_number ?? $request->phone;
        $phone = ($phoneInput === 'null' || empty($phoneInput)) ? null : trim($phoneInput);

        if (empty($email) && empty($phone)) {
            return response()->json([
                'status' => '0',
                'message' => 'Email or Phone Number is required',
            ], 200);
        }

        $phoneVariations = [];
        $nationalNumber = null;

        if (!empty($phone)) {
            $phoneVariations[] = $phone;

            // Handle cases where '+' was decoded as space
            if (strpos($phone, ' ') === 0) {
                $phoneWithPlus = '+' . ltrim($phone);
                $phoneVariations[] = $phoneWithPlus;
                $phone = $phoneWithPlus;
            }

            $cleanPhone = preg_replace('/[^\d+]/', '', $phone);
            if (!empty($cleanPhone)) {
                $phoneVariations[] = $cleanPhone;
            }

            try {
                $phoneUtil = PhoneNumberUtil::getInstance();
                $numberProto = $phoneUtil->parse($phone, null);
                $countryCode = $numberProto->getCountryCode();
                $nationalNumber = (string) $numberProto->getNationalNumber();

                $phoneVariations[] = '+' . $countryCode . '-' . $nationalNumber;
                $phoneVariations[] = '+' . $countryCode . $nationalNumber;
                $phoneVariations[] = $nationalNumber;
            } catch (\Exception $e) {
                $digits = preg_replace('/\D/', '', $phone);
                if (strlen($digits) >= 7) {
                    $nationalNumber = substr($digits, -10);
                }
            }

            $phoneVariations = array_values(array_unique(array_filter($phoneVariations)));
        }

        $site_sort_name = !empty($request->site_sort_name) ? $request->site_sort_name : $this->getSiteSortNameByNumber($request->whatsapp_number);

        // Query all matching customer IDs
        $customerQuery = \App\Models\Customer::where(function ($query) use ($phoneVariations, $nationalNumber, $email) {
            $hasCondition = false;
            if (!empty($phoneVariations)) {
                $query->where(function ($q) use ($phoneVariations, $nationalNumber) {
                    $q->whereIn('phone', $phoneVariations);
                    if (!empty($nationalNumber)) {
                        $q->orWhere('phone', 'like', '%' . $nationalNumber . '%');
                    }
                });
                $hasCondition = true;
            }
            if (!empty($email)) {
                if ($hasCondition) {
                    $query->orWhere('email', $email);
                } else {
                    $query->where('email', $email);
                }
            }
        });

        if (!empty($site_sort_name)) {
            $customerQuery->where('web_sort_name', $site_sort_name);
        }

        $customerIds = $customerQuery->pluck('id')->toArray();

        // 1. First check if user has an order where order_code == '' and pay_status is pending (Lead)
        $leadQuery = \App\Models\Order::where(function ($q) {
            $q->whereNull('order_code')->orWhere('order_code', '');
        })
            ->whereRaw('LOWER(pay_status) = ?', ['pending'])
            ->where('project_status', '!=', 'Not Accepted')
            ->where('internal_pro_status', '!=', 'Cancelled')
            ->where(function ($query) use ($customerIds, $phoneVariations, $nationalNumber, $email) {
                $hasCondition = false;
                if (!empty($customerIds)) {
                    $query->whereIn('cust_id', $customerIds);
                    $hasCondition = true;
                }
                if (!empty($phoneVariations)) {
                    $method = $hasCondition ? 'orWhere' : 'where';
                    $query->$method(function ($q) use ($phoneVariations, $nationalNumber) {
                        $q->whereIn('customer_phone', $phoneVariations);
                        if (!empty($nationalNumber)) {
                            $q->orWhere('customer_phone', 'like', '%' . $nationalNumber . '%');
                        }
                    });
                    $hasCondition = true;
                }
                if (!empty($email)) {
                    $method = $hasCondition ? 'orWhere' : 'where';
                    $query->$method('customer_email', $email);
                }
            });

        if (!empty($site_sort_name)) {
            $leadQuery->where('site_sort_name', $site_sort_name);
        }

        $lead = $leadQuery->orderBy('id', 'desc')->first();

        // If lead found, send the payment link for this order
        if ($lead) {
            $websiteUrl = [
                'GAH' => "https://www.globalassignmenthelp.com/",
                'IAH' => "https://www.instantassignmenthelp.com/",
                'IAH_AU' => "https://www.instantassignmenthelp.com.au/",
                'GAH_AU' => "https://au1.globalassignmenthelp.com.au/",
                'AP' => "https://www.assignmentprime.com/",
                'AD' => "https://www.assignmentdesk.co.uk/"
            ];

            $webName = !empty($lead->site_sort_name) ? $lead->site_sort_name : ($site_sort_name ?? 'GAH');
            $id = !empty($lead->cust_id) ? $lead->cust_id : ($customerIds[0] ?? '');

            $key = base64_encode(
                base64_encode($webName . '?$&@' . $id)
            );

            $paymentLink = ($websiteUrl[$webName] ?? "https://www.globalassignmenthelp.com/")
                . 'whatsaap.php?id=' . $key;

            $lead->payment_link = $paymentLink;

            return response()->json([
                'status' => '1',
                'message' => 'Yes i can see pending order is there you can make the payment through this link-' . $paymentLink,
                'type' => 'leads',
                'data' => [
                    'payment_link' => $paymentLink,
                    'order' => $lead,
                ],
                'payment_link' => $paymentLink,
            ], 200);
        } else {
            // 2. If no lead found, then check where order_code !== '' and pay_status != Complete
            $pendingOrdersQuery = \App\Models\Order::whereNotNull('order_code')
                ->where('order_code', '!=', '')
                ->whereRaw('LOWER(pay_status) != ?', ['complete'])
                ->where('project_status', '!=', 'Not Accepted')
                ->where('internal_pro_status', '!=', 'Cancelled')
                ->where(function ($query) use ($customerIds, $phoneVariations, $nationalNumber, $email) {
                    $hasCondition = false;
                    if (!empty($customerIds)) {
                        $query->whereIn('cust_id', $customerIds);
                        $hasCondition = true;
                    }
                    if (!empty($phoneVariations)) {
                        $method = $hasCondition ? 'orWhere' : 'where';
                        $query->$method(function ($q) use ($phoneVariations, $nationalNumber) {
                            $q->whereIn('customer_phone', $phoneVariations);
                            if (!empty($nationalNumber)) {
                                $q->orWhere('customer_phone', 'like', '%' . $nationalNumber . '%');
                            }
                        });
                        $hasCondition = true;
                    }
                    if (!empty($email)) {
                        $method = $hasCondition ? 'orWhere' : 'where';
                        $query->$method('customer_email', $email);
                    }
                });

            if (!empty($site_sort_name)) {
                $pendingOrdersQuery->where('site_sort_name', $site_sort_name);
            }

            $all_order_codes = (clone $pendingOrdersQuery)
                ->pluck('order_code')
                ->unique()
                ->filter()
                ->implode("\n");

            $order = $pendingOrdersQuery->orderBy('id', 'desc')->first();

            if ($order) {
                // Check payment_source and give payment details
                switch ($order->payment_source) {
                    case 35:
                        $order->bank_details = "Cognus Technology UK Limited\nAcc Number - 00026884\nSORT Code - 77-91-21\nReference - " . $order->order_code;
                        break;
                    case 20:
                        $order->bank_details = "Bank Name- Barclays Bank PLC\nCompany / Payee Name- Optiweb Solutions Ltd\nAccount Number- 43793958\nSort Code - 20 92 63\nSwift Code - BARCGB22\nReference - " . $order->order_code;
                        break;
                    case 27:
                        $order->bank_details = "VERTELIO FINVEST PRIVATE LIMITED\nacc no-004505009256\nIFSC CODE-ICIC0000045\nReference - " . $order->order_code;
                        break;
                    default:
                        $websiteUrl = [
                            'GAH' => "https://www.globalassignmenthelp.com/",
                            'IAH' => "https://www.instantassignmenthelp.com/",
                            'IAH_AU' => "https://www.instantassignmenthelp.com.au/",
                            'GAH_AU' => "https://au1.globalassignmenthelp.com.au/",
                            'AP' => "https://www.assignmentprime.com/",
                            'AD' => "https://www.assignmentdesk.co.uk/"
                        ];
                        $webName = !empty($order->site_sort_name) ? $order->site_sort_name : ($site_sort_name ?? 'GAH');
                        $id = !empty($order->cust_id) ? $order->cust_id : ($customerIds[0] ?? '');
                        $key = base64_encode(base64_encode($webName . '?$&@' . $id));
                        $order->bank_details = ($websiteUrl[$webName] ?? "https://www.globalassignmenthelp.com/") . 'whatsaap.php?id=' . $key;
                        break;
                }

                return response()->json([
                    'status' => '2',
                    'message' => 'I belive you want to make the remaining payment for order
                    order code- ' . $all_order_codes . '
                    pay remaining payment via- '
                        . $order->bank_details,
                    'type' => 'orders',
                    'data' => $order,
                    'order_id' => $order->id,
                    'payment_link' => $order->bank_details,
                    'bank_details' => $order->bank_details,
                    'order_codes' => $all_order_codes
                ], 200);
            }
        }

        return response()->json([
            'status' => '0',
            'message' => 'User not found or no pending records',
            'data' => 'no data found',
            'order_codes' => $all_order_codes ?? ''
        ], 200);
    }

    public function get_pending_payments_leads(Request $request)
    {
        $token = $request->header('token');
        $SECRET_TOKEN = "4a7d1ed414474e4033ac29ccb8653d9b";

        if ($token !== $SECRET_TOKEN) {
            return response()->json([
                'status' => 'error',
                'message' => 'Unauthorized: Invalid token'
            ], 401);
        }

        $email = $request->email === 'null' ? null : $request->email;
        $phone = $request->phone_number === 'null' ? null : $request->phone_number;

        if (empty($email) && empty($phone)) {
            return response()->json([
                'status' => '0',
                'message' => 'Email or Phone Number is required',
            ], 200);
        }

        $formattedPhone = $phone;
        if (!empty($phone)) {
            try {
                $phoneUtil = PhoneNumberUtil::getInstance();
                $numberProto = $phoneUtil->parse($phone, null);
                $countryCode = $numberProto->getCountryCode();
                $nationalNumber = $numberProto->getNationalNumber();
                $formattedPhone = '+' . $countryCode . '-' . $nationalNumber;
            } catch (\Exception $e) {
                $formattedPhone = $phone;
            }
        }

        $site_sort_name = !empty($request->site_sort_name) ? $request->site_sort_name : $this->getSiteSortNameByNumber($request->whatsapp_number);

        $user = \App\Models\Customer::select('id')
            ->when($site_sort_name, function ($q) use ($site_sort_name) {
                return $q->where('web_sort_name', $site_sort_name);
            })
            ->where('phone', '!=', '')
            ->where(function ($query) use ($phone, $formattedPhone) {
                if (!empty($phone)) {
                    $query->where('phone', $phone)
                        ->orWhere('phone', $formattedPhone);
                }
            })
            ->orderBy('id', 'desc')->first();

        if ($user) {

            $lead = \App\Models\Order::where('cust_id', $user->id)
                ->where('order_code', '')
                ->where('project_status', 'Pending')
                ->where('project_status', '!=', 'Not Accepted')
                ->where('internal_pro_status', '!=', 'Cancelled')
                ->when($site_sort_name, function ($q) use ($site_sort_name) {
                    return $q->where('site_sort_name', $site_sort_name);
                })
                ->orderBy('id', 'desc')
                ->first();

            if ($lead) {

                $websiteUrl = [
                    'GAH' => "https://www.globalassignmenthelp.com/",
                    'IAH' => "https://www.instantassignmenthelp.com/",
                    'IAH_AU' => "https://www.instantassignmenthelp.com.au/",
                    'GAH_AU' => "https://au1.globalassignmenthelp.com.au/",
                    'AP' => "https://www.assignmentprime.com/",
                    'AD' => "https://www.assignmentdesk.co.uk/"
                ];

                $webName = $lead->site_sort_name;
                $id = $lead->cust_id;

                $key = base64_encode(
                    base64_encode($webName . '?$&@' . $id)
                );

                $paymentLink = ($websiteUrl[$webName] ?? '')
                    . 'whatsaap.php?id=' . $key;

                return response()->json([
                    'status' => '1',
                    'message' => 'Pending leads found',
                    'type' => 'leads',
                    'data' => [
                        'payment_link' => $paymentLink
                    ]
                ], 200);
            }
        }

        return response()->json([
            'status' => '0',
            'message' => 'User not found or no pending leads',
            'data' => [
                'payment_link' => 0
            ]
        ], 200);
    }

    public function create_order(Request $request)
    {
        $token = $request->header('token') ?: $request->input('token') ?: $request->query('token');

        if ($token !== '1e4e20745582f33c8733ea71f54cf21e') {
            return response()->json([
                'status' => '0',
                'message' => 'Unauthorized: Invalid token',
                'error' => 'Unauthorized: Invalid token. Expected header, query param, or body parameter "token: 1e4e20745582f33c8733ea71f54cf21e"',
                'received_token' => $token
            ], 200);
        }

        $rawWordCount = is_string($request->word_count) || is_numeric($request->word_count) ? trim((string) $request->word_count) : '';
        $cleanWordCount = strtolower($rawWordCount);
        $num = (int) filter_var($rawWordCount, FILTER_SANITIZE_NUMBER_INT);
        $isSlideOrPoster = str_contains($cleanWordCount, 'slide') || str_contains($cleanWordCount, 'ppt') || str_contains($cleanWordCount, 'powerpoint') || str_contains($cleanWordCount, 'poster');

        if (empty($rawWordCount) || (!$isSlideOrPoster && (!preg_match('/\d+/', $rawWordCount) || $num <= 0))) {
            return response()->json([
                'status' => '4',
                'message' => 'Assign to agent'
            ], 200);
        }
        $deadlineInput = $request->deadline;
        if (empty($deadlineInput)) {
            return response()->json([
                'status' => '3',
                'message' => 'deadline is required'
            ], 200);
        }

        $parsedDeadline = $this->parseDeadline($deadlineInput);
        if (!$parsedDeadline) {
            return response()->json([
                'status' => '4',
                'message' => 'Assign to agent'
            ], 200);
        }
        $phone = $request->phone_number;
        if (empty($phone)) {
            return response()->json([
                'status' => '0',
                'message' => 'Phone number is required'
            ], 200);
        }



        $formattedPhone = $phone;
        if (!empty($phone)) {
            try {
                $phoneClassFile = base_path('vendor/giggsey/libphonenumber-for-php/src/PhoneNumberUtil.php');
                if (file_exists($phoneClassFile) && class_exists('\libphonenumber\PhoneNumberUtil')) {
                    $phoneObj = \libphonenumber\PhoneNumberUtil::getInstance();
                    $numberProto = $phoneObj->parse($phone, null);
                    $countryCode = $numberProto->getCountryCode();
                    $nationalNumber = $numberProto->getNationalNumber();
                    $formattedPhone = '+' . $countryCode . '-' . $nationalNumber;
                }
            } catch (\Throwable $e) {
                $formattedPhone = $phone;
            }
        }

        $site_sort_name = !empty($request->site_sort_name) ? $request->site_sort_name : $this->getSiteSortNameByNumber($request->whatsapp_number);

        $customerQuery = \App\Models\Customer::where(function ($query) use ($phone, $formattedPhone) {
            $query->where('phone', $phone)
                ->orWhere('phone', $formattedPhone);
        });

        if (!empty($site_sort_name)) {
            $customerQuery->where('web_sort_name', $site_sort_name);
        }

        $customer = $customerQuery->orderBy('id', 'desc')->first();

        if (!$customer) {
            return response()->json([
                'status' => '0',
                'message' => 'Customer not found'
            ], 200);
        }

        $order = new \App\Models\Order();
        $order->cust_id = $customer->id;
        $order->site_sort_name = $customer->web_sort_name ?? 'UNKNOWN';

        $extractedWords = $request->word_count;
        $deadlineInput = $request->deadline;

        $urgency = $parsedDeadline['urgency'];
        $ddate = $parsedDeadline['ddate'];

        $order->topic = $request->input('topic', 'Assignment');

        $rawWordCount = trim((string) $extractedWords);
        $cleanWordCount = strtolower($rawWordCount);
        $num = (int) filter_var($rawWordCount, FILTER_SANITIZE_NUMBER_INT);

        if (str_contains($cleanWordCount, 'slide') || str_contains($cleanWordCount, 'ppt') || str_contains($cleanWordCount, 'powerpoint')) {
            $serviceName = 'PowerPoint Presentation';
            $pages = $num > 0 ? $num : 1;
            $wordsNum = $pages * 250;
            $wordUnit = $pages . ($pages > 1 ? ' Slides' : ' Slide');
        } elseif (str_contains($cleanWordCount, 'poster')) {
            $serviceName = 'Poster';
            $pages = $num > 0 ? $num : 1;
            $wordsNum = $pages * 250;
            $wordUnit = $pages . ($pages > 1 ? ' Pages / Poster' : ' Page / Poster');
        } elseif (str_contains($cleanWordCount, 'page')) {
            $serviceName = $request->input('service', $request->input('group_name', 'Assignment'));
            $pages = $num > 0 ? $num : 1;
            $wordsNum = $pages * 250;
            $wordUnit = $pages . ' Pages / ' . $wordsNum . ' Words';
        } else {
            $serviceName = $request->input('service', $request->input('group_name', 'Assignment'));
            $wordsNum = $num > 0 ? $num : 250;
            $pages = (int) ceil($wordsNum / 250);
            if ($pages <= 0) {
                $pages = 1;
            }
            $wordUnit = $pages . ' Pages / ' . $wordsNum . ' Words';
        }

        $doctypeArr = [
            'group_name' => $serviceName,
            'subject_name' => '',
        ];
        $order->type = json_encode($doctypeArr);
        $order->words = (string) $wordsNum;
        $order->pages = $pages;
        $order->word_unit = $wordUnit;
        $order->ddate = $ddate;
        $order->urgency = $urgency;

        // Pricing calculation from image table
        $gbpPrice = 0;

        if ($wordsNum < 500) {
            $gbpPrice = 7;
        } elseif ($wordsNum < 1000) {
            $gbpPrice = 10;
        } elseif ($wordsNum < 1500) {
            $gbpPrice = 20;
        } elseif ($wordsNum < 2000) {
            $gbpPrice = 25;
        } elseif ($wordsNum < 2500) {
            $gbpPrice = 30;
        } elseif ($wordsNum < 3000) {
            $gbpPrice = 35;
        } elseif ($wordsNum < 3500) {
            $gbpPrice = 40;
        } elseif ($wordsNum < 4000) {
            $gbpPrice = 50;
        } elseif ($wordsNum < 4500) {
            $gbpPrice = 60;
        } elseif ($wordsNum < 5000) {
            $gbpPrice = 70;
        } elseif ($wordsNum < 5500) {
            $gbpPrice = 75;
        } elseif ($wordsNum < 6000) {
            $gbpPrice = 80;
        } elseif ($wordsNum < 6500) {
            $gbpPrice = 90;
        } elseif ($wordsNum < 7000) {
            $gbpPrice = 95;
        } elseif ($wordsNum < 7500) {
            $gbpPrice = 100;
        } elseif ($wordsNum < 8000) {
            $gbpPrice = 105;
        } elseif ($wordsNum < 8500) {
            $gbpPrice = 110;
        } elseif ($wordsNum < 9000) {
            $gbpPrice = 115;
        } elseif ($wordsNum < 9500) {
            $gbpPrice = 120;
        } elseif ($wordsNum < 10000) {
            $gbpPrice = 125;
        } elseif ($wordsNum < 11000) {
            $gbpPrice = 130;
        } elseif ($wordsNum < 12000) {
            $gbpPrice = 135;
        } elseif ($wordsNum < 13000) {
            $gbpPrice = 140;
        } else {
            $gbpPrice = 145; // 13000+
        }

        $audPrice = $gbpPrice * 2;

        $usdRateHistory = \Illuminate\Support\Facades\DB::table('currency_values_history')
            ->where('currency', 'USD')
            ->orderBy('date', 'desc')
            ->value('value');
        $usdRate = $usdRateHistory ?? \App\Models\CurrencyValues::where('currency', 'USD')->value('value') ?? 1;

        $gbpRateHistory = \Illuminate\Support\Facades\DB::table('currency_values_history')
            ->where('currency', 'GBP')
            ->orderBy('date', 'desc')
            ->value('value');
        $gbpRate = $gbpRateHistory ?? \App\Models\CurrencyValues::where('currency', 'GBP')->value('value') ?? 1;
        $usdPrice = round($gbpPrice / $gbpRate, 2);

        $order->cost = $usdPrice;
        $order->order_currency = 'GBP';

        // Generate Order Code (Basic Example)
        $order->order_code = '';
        $order->style = '';
        $order->level = '2:2 STANDARD';
        $order->pages = $pages;
        $order->sources = '';
        $order->discription = '';
        $order->file1 = '';
        $order->rdate = date('Y-m-d');
        $order->project_status = 'Pending';
        $order->internal_pro_status = 'TBA';
        $order->pay_status = 'Pending';
        $order->paid = 0;
        $order->payment_source = 0;
        $order->due = $order->cost;
        $order->payment_type = 'US$';
        $order->curr_name = 'USD';
        $order->referral = '';
        $order->order_source = 'Whatsapp';
        $order->view = 1;
        $order->feedback_cust_post = 0;
        $order->feedback_admin_post = 0;
        $order->order_from_cust_panel = 0;
        $order->delivered_files = '';
        $order->vendor_order = 0;
        $order->preview_status = 0;
        $order->customer_name = $customer->cust_name ?? '';
        $rawEmail = !empty($request->email) ? trim($request->email) : (!empty($customer->email) ? trim($customer->email) : '');
        $order->customer_email = $this->isValidEmail($rawEmail) ? $rawEmail : '';
        $order->customer_phone = $customer->phone ?? '';
        $order->customer_country = $customer->country ?? '';
        $order->delivered_files_description = '';
        $order->order_from_app = 0;
        $order->assign_project_team = 0;
        $order->assign_quality_team = 0;
        $order->assign_quality_user = 0;
        $order->turnitin_report_price = '';
        $order->cashback_per = 0;
        $order->dtime = date('H:i:s');
        $order->timezone = '';
        $order->price_without_offer = $order->cost;
        $order->pay_payment_gatway_temp = '0';
        $order->word_unit = $wordUnit;
        $order->assign_to = '0';
        $order->moved_from = '0';
        $order->assign_from = '0';
        $order->movetowesite = '0';
        $order->current_value = $gbpRate;
        $order->coupon_info = '';
        $order->wallet_used = '0';
        $order->admin_id = 1;
        $order->created_by = 1;
        $order->gd_admin_id = $customer->gd_admin_id ?? '';
        try {
            $order->save();

            $order_id = $order->id;
            \Illuminate\Support\Facades\DB::table('tb_order_data')->insert([
                'tb_order_id' => $order_id,
                'userid' => $order->cust_id,
                'created_by' => 1,
                'remark' => '',
                'total_redo_count' => '0',
                'feedback_star_mark' => '0',
                'feedback_star_mark_internal' => '0',
                'qualityuser_assign_time' => NULL,
                'project_team_assign_time' => NULL,
                'quality_team_assign_time' => NULL,
                'quality_user_status' => '',
                'internal_description' => '',
                'project_tl_view' => '0',
                'quality_tl_view' => '0',
                'quality_user_view' => '0',
                'chat_post_by_admin' => '0',
                'chat_post_by_user' => '0',
                'tot_feedbak_clint_side' => '0',
                'project_team_notifiaction' => '0',
                'quality_team_notifiaction' => '0',
                'quality_user_notification' => '0',
                'imp_order_for_team' => '0',
                'follow_up_counter' => '0',
                'referral_reward_point_assigned' => '0',
                'followup_status' => '0',
                'order_for_external_writer' => '0',
                'fileready_to_allot_internal' => '0',
                'call_tracking_status' => '0',
                'user_for_call_tracking' => '',
                'call_tracking_teg_user' => '',
                'feedback_priority' => '',
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => '0',
                'message' => 'Failed to save order to database. Some required fields might be missing.',
                'error' => $e->getMessage()
            ], 500);
        }

        // Generate Payment Link
        $websiteUrl = [
            'GAH' => "https://www.globalassignmenthelp.com/",
            'IAH' => "https://www.instantassignmenthelp.com/",
            'IAH_AU' => "https://www.instantassignmenthelp.com.au/",
            'GAH_AU' => "https://au1.globalassignmenthelp.com.au/",
            'AP' => "https://www.assignmentprime.com/",
            'AD' => "https://www.assignmentdesk.co.uk/"
        ];
        $webName = $order->site_sort_name;
        $id = $order->cust_id;
        $key = base64_encode(base64_encode($webName . '?$&@' . $id));
        $payment_link = ($websiteUrl[$webName] ?? '') . 'whatsaap.php?id=' . $key;

        $isAudSite = in_array(strtoupper(trim((string) $webName)), ['GAH_AU', 'AP', 'IAH_AU']);
        $quotationAmount = $isAudSite ? ('AUD ' . $audPrice) : ('GBP ' . $gbpPrice);

        if (!empty($customer->phone) && !empty($webName)) {
            $messageData = [
                'name' => $customer->cust_name ?? 'Customer',
                'siteName' => $webName,
                'order_id' => $order->id,
                'amount' => $quotationAmount,
                'words' => $order->words,
                'topic' => $order->topic,
                'ddate' => date('d M, Y', strtotime($order->ddate)),
                'sendTo' => $customer->phone,
                'userId' => $customer->id,
                'img' => '',
                'document' => ''
            ];
            send_whatsapp('quotation', $messageData);
        }

        if (!empty($order->customer_email) && $this->isValidEmail($order->customer_email)) {
            $this->sendQuotationEmail($order, $customer, $payment_link, $gbpPrice, $audPrice);
        }

        return response()->json([
            'status' => '1',
            'message' => 'Order created successfully',
            'order_id' => $order->id,
            'order_code' => $order->order_code,
            'price' => $order->cost,
            'price_in_gbp' => 'GBP ' . $gbpPrice,
            'price_in_aud' => 'AUD ' . $audPrice,
            'currency' => $order->order_currency,
            'payment_link' => $payment_link,
            'data' => $order
        ], 200);
    }

    private function parseDeadline($deadlineInput)
    {
        if (empty($deadlineInput) || (!is_string($deadlineInput) && !is_numeric($deadlineInput))) {
            return false;
        }

        $urgency = trim((string) $deadlineInput);
        if ($urgency === '') {
            return false;
        }

        // 1. Check hours: e.g. "24 hours", "12 hrs", "in 6 hours", "24hrs"
        if (preg_match('/^\s*(?:in\s+)?(\d+)\s*(?:hours?|hrs?)\s*$/i', $urgency, $m)) {
            $hours = (int) $m[1];
            if ($hours == 24) {
                return [
                    'urgency' => '1 Day',
                    'ddate' => date('Y-m-d H:i:s', strtotime('+1 day'))
                ];
            } elseif ($hours > 0) {
                return [
                    'urgency' => $hours . ' Hours',
                    'ddate' => date('Y-m-d H:i:s', strtotime("+$hours hours"))
                ];
            }
        }

        // 2. Check days: e.g. "1 day", "2 days", "in 3 days", "3days"
        if (preg_match('/^\s*(?:in\s+)?(\d+)\s*days?\s*$/i', $urgency, $m)) {
            $days = (int) $m[1];
            if ($days > 0) {
                return [
                    'urgency' => $days . ($days == 1 ? ' Day' : ' Days'),
                    'ddate' => date('Y-m-d H:i:s', strtotime("+$days days"))
                ];
            }
        }

        // 3. Check weeks: e.g. "1 week", "2 weeks", "in 2 weeks", "1 wk"
        if (preg_match('/^\s*(?:in\s+)?(\d+)\s*(?:weeks?|wks?)\s*$/i', $urgency, $m)) {
            $weeks = (int) $m[1];
            if ($weeks > 0) {
                $days = $weeks * 7;
                return [
                    'urgency' => $days . ' Days',
                    'ddate' => date('Y-m-d H:i:s', strtotime("+$days days"))
                ];
            }
        }

        // 4. Check ordinal day like "15th", "25th", "1st", "2nd", "3rd"
        if (preg_match('/^\s*(\d{1,2})(?:st|nd|rd|th)\s*$/i', $urgency, $m)) {
            $dayNum = (int) $m[1];
            if ($dayNum >= 1 && $dayNum <= 31) {
                $currentMonthYear = date('Y-m');
                $targetTime = strtotime("$currentMonthYear-$dayNum");
                if ($targetTime !== false) {
                    if ($targetTime < strtotime('today')) {
                        $targetTime = strtotime('+1 month', $targetTime);
                    }
                    $today = new \DateTime(date('Y-m-d'));
                    $target = new \DateTime(date('Y-m-d', $targetTime));
                    $diff = $today->diff($target);
                    $days = $diff->invert ? -$diff->days : $diff->days;
                    if ($days <= 0) {
                        $days = 1;
                    }
                    return [
                        'urgency' => $days . ($days == 1 ? ' Day' : ' Days'),
                        'ddate' => date('Y-m-d', $targetTime) . ' ' . date('H:i:s')
                    ];
                }
            }
        }

        // 5. General date parsing
        $clean = trim($urgency);
        $cleanWithoutPrefix = preg_replace('/^(?:by|before|on|due\s+on|due)\s+/i', '', $clean);
        $normalized = preg_replace('/[.\/]/', '-', $cleanWithoutPrefix);

        $time = strtotime($normalized);
        if ($time === false) {
            $time = strtotime($cleanWithoutPrefix);
        }
        if ($time === false) {
            $time = strtotime(preg_replace('/[.\/]/', '-', $clean));
        }
        if ($time === false) {
            $time = strtotime($clean);
        }

        // Handle date without year like "15-10" or "10/12"
        if ($time === false && preg_match('/^\d{1,2}-\d{1,2}$/', $normalized)) {
            $time = strtotime($normalized . '-' . date('Y'));
            if ($time === false) {
                $parts = explode('-', $normalized);
                $time = strtotime(date('Y') . '-' . $parts[1] . '-' . $parts[0]);
            }
        }

        // If no 4-digit year was provided and the date is already past in current year, roll forward to next year
        if ($time !== false && $time < strtotime('today') && !preg_match('/\b(19|20)\d{2}\b/', $clean)) {
            $nextYearTime = strtotime('+1 year', $time);
            if ($nextYearTime !== false) {
                $time = $nextYearTime;
            }
        }

        if ($time !== false) {
            $today = new \DateTime(date('Y-m-d'));
            $target = new \DateTime(date('Y-m-d', $time));
            $diff = $today->diff($target);
            $days = ($diff->invert ? -$diff->days : $diff->days);

            if ($days <= 0) {
                $days = 1;
            }

            $urgencyStr = $days . ($days == 1 ? ' Day' : ' Days');

            if (date('H:i:s', $time) === '00:00:00') {
                $ddateStr = date('Y-m-d', $time) . ' ' . date('H:i:s');
            } else {
                $ddateStr = date('Y-m-d H:i:s', $time);
            }

            return [
                'urgency' => $urgencyStr,
                'ddate' => $ddateStr
            ];
        }

        return false;
    }

    private function isValidEmail(?string $email): bool
    {
        if (empty($email)) {
            return false;
        }
        $email = trim($email);
        return str_contains($email, '@') && str_contains($email, '.') && filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
    }

    private function sendQuotationEmail($order, $customer, $paymentLink, $gbpPrice, $audPrice = null)
    {
        if ($audPrice === null) {
            $audPrice = $gbpPrice * 2;
        }

        if (empty($customer->email) || !$this->isValidEmail($customer->email))
            return false;

        $websiteDetails = \App\Models\website::where('sortname', $order->site_sort_name)->first();
        if (!$websiteDetails)
            return false;

        $template = \App\Models\Emailtemplate::where('templates_type_id', 18)
            ->where('website_sortname', $order->site_sort_name)
            ->where('status', 0)
            ->first();

        if (!$template)
            return false;

        $host = str_replace('ssl://', '', $websiteDetails->mail_host);
        $message = $template->message ?? '';
        $subject = $template->subject ?? 'Your Quotation';

        // Basic Replacements
        $message = str_replace("CLIENT_NAME", $customer->cust_name, $message);
        $message = str_replace("CLIENT_EMAIL", $customer->email, $message);
        $message = str_replace("CLIENT_PASSWORD", $customer->customer_password_md5_decode, $message);
        $message = str_replace("WEBSITE_MAIL", $websiteDetails->sendto, $message);
        $message = str_replace("SITE_TITLE_NAME", $websiteDetails->name, $message);

        $siteUrl = rtrim($websiteDetails->url, '/') . '/';
        $message = str_replace("WEB_ADDRESS", $siteUrl, $message);

        // Build Table
        $isAudSite = in_array(strtoupper(trim((string) $order->site_sort_name)), ['GAH_AU', 'AP', 'IAH_AU']);
        $amountDisplay = $isAudSite ? ('AUD ' . $audPrice) : ('GBP ' . $gbpPrice);

        $dataTable = '
        <table style="width:100%; max-width:760px; font-family:Arial, sans-serif; border-collapse: collapse;">
            <tr>
                <td style="border-bottom:1px solid #DBDBDB; padding:10px 0;">
                    <p style="margin: 0 0 3px 0; color: #0B1E46; font-weight:bold; font-size: 15px;">' . $order->id . ' / ' . $order->topic . '</p>
                    <p style="margin: 0; color: #616161; font-size: 13px;">Deadline: ' . $order->urgency . '</p>
                </td>
                <td style="border-bottom:1px solid #DBDBDB; text-align:right; padding:10px 0;">
                    <p style="margin: 0; color: #0B1E46; font-weight:bold; font-size: 15px;">' . $amountDisplay . '</p>
                </td>
            </tr>
        </table>';

        $payBtn = '<div style="text-align:center;"><a href="' . $paymentLink . '" style="background-image: linear-gradient(to right, #0f9dd1 0%, #0c69ad 41%, #0f9dd1 100%); color:#fff; padding:13px 20px; text-decoration:none; border-radius:3px; display:inline-block; font-weight:bold; width: 180px; text-align: center;">Pay Now</a></div>';

        $loginTable = '
        <table cellspacing="0" cellpadding="0" style="width:100%; font-family:Arial; font-size:14px; margin:20px 0;">
            <tr>
                <td style="border: 1px dashed #ccc; padding:8px; background: #f9f9fa; color:#005db7; font-weight: 600; width:35%;">Login Credentials</td>
                <td style="border: 1px dashed #ccc; border-left:0; padding:8px 15px; background: #f9f9fa; width:65%;">
                    <strong>Username</strong>: ' . $customer->email . '<br>
                    <strong>Password</strong>: ' . $customer->customer_password_md5_decode . '
                </td>
            </tr>
        </table>';

        $message = str_replace("TABLE_PAYPAL_DATA", $dataTable, $message);
        $message = str_replace("TABLE_LOGIN_DETAIL", $loginTable, $message);
        $message = str_replace("PAYPALLINK", $payBtn, $message);

        // Remove unreplaced placeholders
        $message = preg_replace('/(ADMIN_PHONE|WHATSUP_NO|ADMIN_PHONE[1-4]|UNIQUE_STRING_ID)/', '', $message);

        // Dynamic Mail Configuration
        $host = str_replace('ssl://', '', $websiteDetails->mail_host);
        \Illuminate\Support\Facades\Config::set('mail.mailers.smtp', [
            'transport' => 'smtp',
            'host' => $host,
            'port' => $websiteDetails->mail_port,
            'encryption' => 'ssl',
            'username' => $websiteDetails->sendto,
            'password' => $websiteDetails->mail_password,
            'timeout' => null,
            'auth_mode' => null,
        ]);
        \Illuminate\Support\Facades\Config::set('mail.from.address', $websiteDetails->sendto);
        \Illuminate\Support\Facades\Config::set('mail.from.name', $websiteDetails->name);

        try {
            \Illuminate\Support\Facades\Mail::html($message, function ($mailMessage) use ($websiteDetails, $subject, $customer) {
                $mailMessage->to($customer->email)
                    ->subject($subject)
                    ->from($websiteDetails->sendto, $websiteDetails->name);
            });
            return true;
        } catch (\Exception $e) {
            \Illuminate\Support\Facades\Log::error('Quotation Email Failed: ' . $e->getMessage());
            return false;
        }
    }

    public function create_order_new_customer(Request $request)
    {
        $token = $request->header('token') ?: $request->input('token') ?: $request->query('token');

        if ($token !== '1e4e20745582f33c8733ea71f54cf21e') {
            return response()->json([
                'status' => '0',
                'message' => 'Unauthorized: Invalid token',
                'error' => 'Unauthorized: Invalid token. Expected header, query param, or body parameter "token: 1e4e20745582f33c8733ea71f54cf21e"',
                'received_token' => $token
            ], 200);
        }

        $phone = is_string($request->phone_number) ? trim($request->phone_number) : (string) $request->phone_number;
        if (empty($phone)) {
            return response()->json([
                'status' => '0',
                'message' => 'Phone number is required'
            ], 200);
        }
        $rawWordCount = is_string($request->word_count) || is_numeric($request->word_count) ? trim((string) $request->word_count) : '';
        $cleanWordCount = strtolower($rawWordCount);
        $num = (int) filter_var($rawWordCount, FILTER_SANITIZE_NUMBER_INT);
        $isSlideOrPoster = str_contains($cleanWordCount, 'slide') || str_contains($cleanWordCount, 'ppt') || str_contains($cleanWordCount, 'powerpoint') || str_contains($cleanWordCount, 'poster');

        if (empty($rawWordCount) || (!$isSlideOrPoster && (!preg_match('/\d+/', $rawWordCount) || $num <= 0))) {
            return response()->json([
                'status' => '4',
                'message' => 'Assign to agent'
            ], 200);
        }
        $deadlineInput = is_string($request->deadline) || is_numeric($request->deadline) ? trim((string) $request->deadline) : '';
        if (empty($deadlineInput)) {
            return response()->json([
                'status' => '3',
                'message' => 'deadline is required'
            ], 200);
        }

        $parsedDeadline = $this->parseDeadline($deadlineInput);
        if (!$parsedDeadline) {
            return response()->json([
                'status' => '4',
                'message' => 'Assign to agent'
            ], 200);
        }
        $email = is_string($request->email) ? trim($request->email) : '';
        if (empty($email) || $email === 'null') {
            return response()->json([
                'status' => '0',
                'message' => 'Email is required'
            ], 200);
        }

        if (!$this->isValidEmail($email)) {
            return response()->json([
                'status' => '0',
                'message' => 'Invalid email format'
            ], 200);
        }

        $formattedPhone = $phone;
        $countryName = '';
        if (!empty($phone)) {
            try {
                $phoneClassFile = base_path('vendor/giggsey/libphonenumber-for-php/src/PhoneNumberUtil.php');
                if (file_exists($phoneClassFile) && class_exists('\libphonenumber\PhoneNumberUtil')) {
                    $phoneObj = \libphonenumber\PhoneNumberUtil::getInstance();
                    $numberProto = $phoneObj->parse($phone, null);
                    $countryCode = $numberProto->getCountryCode();
                    $nationalNumber = $numberProto->getNationalNumber();
                    $formattedPhone = '+' . $countryCode . '-' . $nationalNumber;

                    $countryName = \Illuminate\Support\Facades\DB::table('country')
                        ->where('code', $countryCode)
                        ->value('name') ?? '';
                }
            } catch (\Throwable $e) {
                $formattedPhone = $phone;
            }
        }

        $site_sort_name = $this->getSiteSortNameByNumber($request->whatsapp_number) ?: $request->site_sort_name;

        $name = is_string($request->name) ? trim($request->name) : 'New Customer';

        $customerQuery = \App\Models\Customer::where(function ($query) use ($phone, $formattedPhone) {
            $query->where('phone', $phone)
                ->orWhere('phone', $formattedPhone);
        });

        if (!empty($site_sort_name)) {
            $customerQuery->where('web_sort_name', $site_sort_name);
        }

        $customer = $customerQuery->orderBy('id', 'desc')->first();

        // Fallback: search across any site
        if (!$customer) {
            $customer = \App\Models\Customer::where(function ($query) use ($phone, $formattedPhone) {
                $query->where('phone', $phone)
                    ->orWhere('phone', $formattedPhone);
            })->orderBy('id', 'desc')->first();
        }

        // Fallback: search by email
        if (!$customer && !empty($email)) {
            $customer = \App\Models\Customer::where('email', $email)->orderBy('id', 'desc')->first();
        }

        if ($customer) {
            $customer->email = $email;
            $customer->save();
        } else {
            // Auto-create customer for new customer endpoint
            $password = md5('user123');
            $ipAddress = $_SERVER['REMOTE_ADDR'] ?? '';
            $customer = \App\Models\Customer::create([
                'cust_name' => !empty($name) ? $name : 'New Customer',
                'password' => $password,
                'email' => $email,
                'status' => 1,
                'phone' => $formattedPhone ?: $phone,
                'country' => $countryName ?: ($request->country ?? ''),
                'customer_password_md5_decode' => 'user123',
                'lead_source' => 'Whatsapp',
                'web_sort_name' => $site_sort_name ?? 'GAH',
                'BD_name' => '',
                'promotion_status' => 0,
                'activate' => 0,
                'storecredit' => 0,
                'image' => '',
                'city' => '',
                'address' => '',
                'link' => '',
                'verify' => 0,
                'view' => 0,
                'rwards_point' => 0,
                'online' => 0,
                'ip_address' => $ipAddress,
                'customer_type' => 0,
                'vendor_view' => 0,
                'vendor_cust_deleted_status' => 0,
                'customer_from' => 0,
                'other_info' => '',
                'auto_mail_send' => 0,
                'payment_getway_token' => '',
                'alternate_phone' => '',
                'alternate_email' => '',
                'email_verify' => 0,
                'phone_verify' => 0,
                'assign_to' => 0,
                'refered_by' => 0,
                'whatsapp_status' => 0,
                'qualification' => '',
                'college' => '',
                'coupon' => '',
                'course' => '',
                'zendesk_ticket_id' => 0,
                'stage' => 'Enquiry',
            ]);

            if (class_exists('\App\Models\UserLog')) {
                try {
                    \App\Models\UserLog::create([
                        'user_id' => $customer->id,
                        'old_event' => 'Enquiry',
                        'event_type' => 'Stage',
                        'changed_by' => 1,
                        'changed_at' => now()
                    ]);
                } catch (\Throwable $e) {
                }
            }
        }

        $request->merge([
            'phone_number' => $formattedPhone ?: $phone,
            'email' => $email,
            'word_count' => $rawWordCount,
            'deadline' => $deadlineInput,
            'site_sort_name' => $site_sort_name,
            'name' => $name,
            'token' => $token,
        ]);

        return $this->create_order($request);
    }

    private function getSiteSortNameByNumber($whatsapp_number)
    {
        if (empty($whatsapp_number)) {
            return null;
        }

        $clean_number = str_replace(' ', '', $whatsapp_number);

        $mapping = [
            '+447400010488' => 'IAH',
            '+16073649807' => 'GAH',
            '+447723580422' => 'IAH_M',
            '+61483933655' => 'AP',
            '+61483982483' => 'GAH_AU',
            '+447575438880' => 'GAH',
            '+447782590068' => 'AD (ZD)',
            '+17753738777' => 'IAH',
            '+61482070482' => 'IAH_AU',
            '+447700173657' => 'GAH_2',
            '+447403375889' => 'AD',
            '+447403300274' => 'AD'
        ];

        return $mapping[$clean_number] ?? null;
    }

    public function get_services(Request $request)
    {
        $token = $request->header('token');
        $SECRET_TOKEN = "8f4d9b2e1a3c7f605d8e2b9c4a1f3b7d";
        if ($token !== $SECRET_TOKEN) {
            return response()->json([
                'status' => 'error',
                'message' => 'Unauthorized: Invalid token'
            ], 401);
        }

        $services = [
            ['id' => '1', 'name' => 'Assignment | Coursework | Term Paper', 'unit_tag' => 'Pages | Words'],
            ['id' => '14', 'name' => 'Case Study | Report Writing', 'unit_tag' => 'Pages | Words'],
            ['id' => '17', 'name' => 'Plagiarism Report', 'unit_tag' => 'Pages | Words'],
            ['id' => '16', 'name' => 'Essay', 'unit_tag' => 'Pages | Words'],
            ['id' => '2', 'name' => 'Dissertation & PHD Thesis', 'unit_tag' => 'Pages | Words'],
            ['id' => '13', 'name' => 'Business Plan', 'unit_tag' => 'Pages | Words'],
            ['id' => '4', 'name' => 'Online Exam | Question based test Papers', 'unit_tag' => 'Que. | Word/Que.'],
            ['id' => '15', 'name' => 'Multiple Choice Questions', 'unit_tag' => 'Que. | Word/Que.'],
            ['id' => '5', 'name' => 'Editing | Proofreading | Paraphrasing', 'unit_tag' => 'Pages | Words'],
            ['id' => '8', 'name' => 'PowerPoint Presentation', 'unit_tag' => 'Slides'],
            ['id' => '9', 'name' => 'Poster', 'unit_tag' => 'Poster'],
            ['id' => '10', 'name' => 'Leaflet', 'unit_tag' => 'Leaflet'],
            ['id' => '6', 'name' => 'Summary Writing', 'unit_tag' => 'Pages | Words'],
            ['id' => '7', 'name' => 'Portfolio', 'unit_tag' => 'Pages | Words'],
            ['id' => '11', 'name' => 'Resume / CV Services', 'unit_tag' => 'Pages | Words'],
        ];

        return response()->json([
            'status' => '1',
            'message' => 'Services retrieved successfully',
            'data' => $services
        ], 200);
    }

    public function update_file(Request $request)
    {
        $token = $request->header('token');
        if ($token !== 'b371190226343542279188e4428a2a72') {
            return response()->json([
                'status' => 'error',
                'message' => 'Unauthorized: Invalid token'
            ], 401);
        }

        $orderId = $request->order_id;
        if (empty($orderId) || $orderId === 'null') {
            $orderId = $request->order_id1;
        }

        if (empty($orderId) || $orderId === 'null') {
            return response()->json([
                'status' => '0',
                'message' => 'order_id is required'
            ], 400);
        }

        $order = \App\Models\Order::find($orderId);
        if (!$order) {
            return response()->json([
                'status' => '0',
                'message' => 'Order not found'
            ], 404);
        }

        if (!$request->hasFile('file') || !$request->file('file')->isValid()) {
            return response()->json([
                'status' => '0',
                'message' => 'Valid file is required'
            ], 400);
        }

        $file = $request->file('file');

        // Save to S3
        $originalName = $file->getClientOriginalName();
        $ext = $file->getClientOriginalExtension();
        $name = \Illuminate\Support\Str::limit(pathinfo($originalName, PATHINFO_FILENAME), 10, '') . '_' . rand() . '.' . $ext;

        $webName = $order->site_sort_name ?? 'UNKNOWN';
        $path = "{$webName}/{$name}";
        $s3 = \Illuminate\Support\Facades\Storage::disk('s3');
        $s3->put($path, file_get_contents($file), 'public');

        // Append to existing file1 column
        $existingFiles = trim($order->file1);
        if (!empty($existingFiles)) {
            $order->file1 = $existingFiles . '?|@$' . $name;
        } else {
            $order->file1 = $name;
        }

        $order->save();

        return response()->json([
            'status' => '1',
            'message' => 'File added successfully',
            'order_id' => $order->id,
            'file' => $order->file1,
            'data' => $order
        ], 200);
    }

    public function update_order(Request $request)
    {
        $token = $request->header('token');
        if ($token !== 'b371190226343542279188e4428a2a72') {
            return response()->json([
                'status' => 'error',
                'message' => 'Unauthorized: Invalid token'
            ], 401);
        }

        $orderId = $request->order_id;
        if (empty($orderId) || $orderId === 'null') {
            $orderId = $request->order_id1;
        }

        if (empty($orderId) || $orderId === 'null') {
            return response()->json([
                'status' => '0',
                'message' => 'order_id is required'
            ], 400);
        }

        $order = \App\Models\Order::find($orderId);
        if (!$order) {
            return response()->json([
                'status' => '0',
                'message' => 'Order not found'
            ], 404);
        }

        if (!$request->hasFile('file') || !$request->file('file')->isValid()) {
            return response()->json([
                'status' => '0',
                'message' => 'Valid file is required'
            ], 400);
        }

        $file = $request->file('file');

        // Save to S3
        $originalName = $file->getClientOriginalName();
        $ext = $file->getClientOriginalExtension();
        $name = \Illuminate\Support\Str::limit(pathinfo($originalName, PATHINFO_FILENAME), 10, '') . '_' . rand() . '.' . $ext;

        $webName = $order->site_sort_name ?? 'UNKNOWN';
        $path = "{$webName}/{$name}";
        $s3 = \Illuminate\Support\Facades\Storage::disk('s3');
        $s3->put($path, file_get_contents($file), 'public');

        // Update file column
        $order->file1 = $name;

        // Process file for extraction
        $tempFile = $file->getPathname();
        $tempFileWithExt = $tempFile . '.' . $ext;
        copy($tempFile, $tempFileWithExt);

        $extractedData = null;
        $extractionError = null;
        $courseCode = '';

        try {
            $extractionUrl = 'https://drafting.chillyinc.com/api/extract';

            $cfile = new \CURLFile($tempFileWithExt, mime_content_type($tempFileWithExt), $name);

            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $extractionUrl);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, ['file' => $cfile]);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_TIMEOUT, 120);
            curl_setopt($ch, CURLOPT_HTTPHEADER, [
                'Cookie: auth_token=bypass_token',
                'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
                'Accept: application/json, text/plain, */*',
                'Accept-Language: en-US,en;q=0.9',
                'Connection: keep-alive',
                'Referer: https://drafting.chillyinc.com/',
                'Origin: https://drafting.chillyinc.com'
            ]);

            $responseBody = curl_exec($ch);
            $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            \Illuminate\Support\Facades\Log::info("AutoDrafting Extraction API Status: " . $httpcode);
            \Illuminate\Support\Facades\Log::info("AutoDrafting Extraction API Body: " . $responseBody);

            if ($httpcode >= 200 && $httpcode < 300) {
                $extractedData = json_decode($responseBody, true);
            } else {
                $extractionError = "API Error ($httpcode): " . $responseBody;
                \Illuminate\Support\Facades\Log::error("AutoDrafting Extraction failed: " . $responseBody);
            }

            // Extract course_code / module_code from API result or via local file fallback
            $courseCode = !empty($extractedData['course_code']) ? $extractedData['course_code'] : (!empty($extractedData['module_code']) ? $extractedData['module_code'] : '');
            if (empty($courseCode) && file_exists($tempFileWithExt)) {
                $extractedText = '';
                $fileExt = strtolower($ext);
                if (in_array($fileExt, ['docx', 'doc'])) {
                    $zip = new \ZipArchive();
                    if ($zip->open($tempFileWithExt) === TRUE) {
                        $xml = $zip->getFromName('word/document.xml');
                        $zip->close();
                        if ($xml) {
                            $extractedText = preg_replace('/<[^>]+>/', ' ', $xml);
                        }
                    }
                } elseif ($fileExt === 'pdf') {
                    if (file_exists('/usr/bin/pdftotext')) {
                        $extractedText = @shell_exec('/usr/bin/pdftotext ' . escapeshellarg($tempFileWithExt) . ' - 2>/dev/null');
                    }
                } elseif (in_array($fileExt, ['txt', 'rtf', 'md'])) {
                    $extractedText = @file_get_contents($tempFileWithExt);
                }

                if (!empty($extractedText)) {
                    $codePattern = '/(?:module|course|unit|subject)\s*(?:code|no|number|id)\s*[:\-–]?\s*([A-Za-z0-9]{2,10}(?:[\s\-_][A-Za-z0-9]{2,10})?)|(?:module|course|unit|subject)\s*[:\-–]?\s*([A-Za-z]{1,6}\s*[-_]?\s*\d{2,6}[A-Za-z0-9]*)/i';
                    if (preg_match($codePattern, $extractedText, $matches)) {
                        $courseCode = trim(!empty($matches[1]) ? $matches[1] : $matches[2]);
                    }
                }
            }

            if (!empty($courseCode) && is_array($extractedData)) {
                $extractedData['course_code'] = $courseCode;
            }

            @unlink($tempFileWithExt);
        } catch (\Exception $e) {
            @unlink($tempFileWithExt);
            $extractionError = "Connection Error: " . $e->getMessage();
            \Illuminate\Support\Facades\Log::error("AutoDrafting API Call Error: " . $e->getMessage());
        }

        if ($extractedData && !empty($extractedData['success'])) {
            if (!empty($extractedData['service']) || !empty($extractedData['subject'])) {
                $currentType = json_decode($order->type, true) ?? [];
                $groupName = !empty($extractedData['service']) ? $extractedData['service'] : ($currentType['group_name'] ?? 'Assignment');
                $subjectName = !empty($extractedData['subject']) ? $extractedData['subject'] : ($currentType['subject_name'] ?? '');

                $doctypeArr = [
                    'group_name' => $groupName,
                    'subject_name' => $subjectName,
                ];
                $order->type = json_encode($doctypeArr);
            }

            if (!empty($extractedData['topic'])) {
                $order->topic = $extractedData['topic'];
            }

            if (!empty($extractedData['word_count'])) {
                $extractedWords = $extractedData['word_count'];
                $order->words = $extractedWords;
                $wordsNum = (int) filter_var($extractedWords, FILTER_SANITIZE_NUMBER_INT);
                if ($wordsNum > 0) {
                    $order->pages = ceil($wordsNum / 250);
                    $order->word_unit = $order->pages . ' Pages / ' . $wordsNum . ' Words';
                }
            }

            if (!empty($extractedData['deadline'])) {
                $urgency = $extractedData['deadline'];
                $order->urgency = $urgency;

                if (stripos($urgency, 'Hour') !== false) {
                    $hours = (int) filter_var($urgency, FILTER_SANITIZE_NUMBER_INT);
                    if ($hours == 24) {
                        $order->urgency = '1 Day';
                        $order->ddate = date('Y-m-d H:i:s', strtotime("+1 day"));
                    } elseif ($hours > 0) {
                        $order->ddate = date('Y-m-d H:i:s', strtotime("+$hours hours"));
                    }
                } elseif (stripos($urgency, 'Day') !== false) {
                    $days = (int) filter_var($urgency, FILTER_SANITIZE_NUMBER_INT);
                    if ($days > 0) {
                        $order->ddate = date('Y-m-d H:i:s', strtotime("+$days days"));
                    }
                } else {
                    $time = strtotime($urgency);
                    if ($time !== false) {
                        $order->ddate = date('Y-m-d H:i:s', $time);
                        $diff = $time - time();
                        $days = ceil($diff / (60 * 60 * 24));
                        if ($days <= 0)
                            $days = 1;
                        $order->urgency = $days . ' Days';
                    } else {
                        $order->ddate = date('Y-m-d H:i:s', strtotime('+7 days'));
                        $order->urgency = '7 Days';
                    }
                }
            }

            try {
                $insertData = [
                    'order_id' => $order->id,
                    'order_code' => !empty($order->order_code) ? mb_substr($order->order_code, 0, 10) : '',
                    'topic' => mb_substr($extractedData['topic'] ?? ($order->topic ?? ''), 0, 250),
                    'words' => (isset($wordsNum) && $wordsNum > 0) ? $wordsNum : ((int) filter_var($order->words ?? '', FILTER_SANITIZE_NUMBER_INT) ?: 0),
                    'subject' => mb_substr($extractedData['subject'] ?? ($subjectName ?? ''), 0, 100),
                    'paper_type' => mb_substr($extractedData['service'] ?? ($groupName ?? ''), 0, 100),
                    'university' => mb_substr($extractedData['university_name'] ?? ($extractedData['university'] ?? ''), 0, 100),
                    'college_name' => !empty($extractedData['college']) ? mb_substr($extractedData['college'], 0, 255) : (!empty($extractedData['college_name']) ? mb_substr($extractedData['college_name'], 0, 255) : null),
                    'submission_deadline' => !empty($extractedData['deadline']) ? mb_substr($extractedData['deadline'], 0, 255) : (!empty($order->ddate) ? mb_substr($order->ddate, 0, 255) : null),
                    'website' => mb_substr($order->site_sort_name ?? '', 0, 10),
                    'file' => mb_substr($name ?? ($order->file1 ?? ''), 0, 250),
                    'unit_no' => mb_substr($order->pages ? (string) $order->pages : '', 0, 20),
                    'country' => mb_substr($order->customer_country ?? '', 0, 50),
                    'course_code' => !empty($courseCode) ? mb_substr($courseCode, 0, 50) : (
                        !empty($extractedData['course_code']) ? mb_substr($extractedData['course_code'], 0, 50) : (
                            !empty($extractedData['module_code']) ? mb_substr($extractedData['module_code'], 0, 50) : ''
                        )
                    ),
                    'organisation_selected' => '',
                    'level' => 0,
                    'heading' => '',
                    'permalink' => '',
                    'meta_title' => '',
                    'meta_description' => '',
                    'meta_keywords' => '',
                    'question' => '',
                    'content' => '',
                    'status' => 0,
                    'comment' => '',
                    'ppt_status' => 0,
                    'answer' => '',
                    'answer_chk' => 0,
                    'degree_name' => null,
                    'course_name' => null,
                    'checked_out' => null,
                    'created_by' => 0,
                    'modified_by' => 0,
                    'state' => 0,
                    'ordering' => 0,
                ];

                \Illuminate\Support\Facades\DB::table('temp_samples')->insert($insertData);
                \Illuminate\Support\Facades\Log::info("Inserted new row into temp_samples for order_id: " . $order->id . " (order_code: " . ($order->order_code ?? '') . ")");
            } catch (\Exception $e) {
                \Illuminate\Support\Facades\Log::error("Failed to save extracted data in temp_samples: " . $e->getMessage());
            }
        }

        $order->save();

        return response()->json([
            'status' => '1',
            'message' => 'Order updated successfully',
            'order_id' => $order->id,
            'file' => $order->file1,
            'extracted_data' => $extractedData ?? null,
            'saved_extracted_detail' => !empty($extractedData['success']),
            'extraction_error' => $extractionError,
            //   'data' => $order
        ], 200);
    }

    public function check_email(Request $request)
    {
        $token = $request->header('token');
        $SECRET_TOKEN = "8f4d9b2e1a3c7f605d8e2b9c4a1f3b7d";
        if ($token !== $SECRET_TOKEN) {
            return response()->json([
                'status' => 'error',
                'message' => 'Unauthorized: Invalid token'
            ], 401);
        }

        $email = $request->email;
        if (empty($email) || $email === 'null' || (is_string($email) && trim($email) === '')) {
            return response()->json([
                'status' => '0',
                'is_valid' => false,
                'message' => 'Email is required'
            ], 400);
        }

        $email = trim((string) $email);

        // Format & Syntax Validation
        if (!$this->isValidEmail($email)) {
            return response()->json([
                'status' => '0',
                'is_valid' => false,
                'email' => $email,
                'message' => 'Invalid email format'
            ], 200);
        }

        return response()->json([
            'status' => '1',
            'is_valid' => true,
            'email' => $email,
            'message' => 'Email is valid'
        ], 200);
    }

    /**
     * Get users whose stage entered date is today (or a specified date)
     * Useful for automated workflows (e.g. n8n WhatsApp campaigns)
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function whatsappDailyUsersByStage(Request $request)
    {
        $token = $request->header('token') ?: $request->bearerToken() ?: $request->input('token');
        $validTokens = [
            '8f4d9b2e1a3c7f605d8e2b9c4a1f3b7d',
            '1e4e20745582f33c8733ea71f54cf21e',
            'b371190226343542279188e4428a2a72'
        ];

        if (!in_array($token, $validTokens)) {
            return response()->json([
                'status' => 'error',
                'message' => 'Unauthorized: Invalid token'
            ], 401);
        }

        // Date to filter by - defaults to today
        $targetDate = $request->input('date', date('Y-m-d'));

        // Optional filters
        $stageFilter = $request->input('stage');
        $stagesFilter = $request->input('stages');
        $websiteFilter = $request->input('website', $request->input('site_sort_name'));

        $query = "
            SELECT 
                u.id,
                u.cust_name,
                u.email,
                u.phone,
                u.stage,
                u.web_sort_name,
                u.country,
                COALESCE(latest_log.changed_at, u.created) as stage_entered_date,
                latest_log.old_event as previous_stage
            FROM users u
            LEFT JOIN (
                SELECT ul.user_id, ul.new_event, ul.old_event, ul.changed_at
                FROM user_logs ul
                INNER JOIN (
                    SELECT user_id, MAX(id) as max_id
                    FROM user_logs
                    WHERE event_type = 'Stage'
                    GROUP BY user_id
                ) latest ON ul.id = latest.max_id
            ) latest_log ON latest_log.user_id = u.id
            WHERE (
                DATE(latest_log.changed_at) = ?
                OR (latest_log.changed_at IS NULL AND DATE(u.created) = ?)
            )
        ";

        $bindings = [$targetDate, $targetDate];

        if (!empty($stageFilter)) {
            $query .= " AND u.stage = ?";
            $bindings[] = $stageFilter;
        } elseif (!empty($stagesFilter)) {
            $stagesArray = array_filter(array_map('trim', explode(',', $stagesFilter)));
            if (!empty($stagesArray)) {
                $placeholders = implode(',', array_fill(0, count($stagesArray), '?'));
                $query .= " AND u.stage IN ($placeholders)";
                $bindings = array_merge($bindings, $stagesArray);
            }
        }

        if (!empty($websiteFilter)) {
            $query .= " AND u.web_sort_name = ?";
            $bindings[] = $websiteFilter;
        }

        $query .= " ORDER BY stage_entered_date DESC";

        $limit = (int) $request->input('limit', 0);
        $offset = (int) $request->input('offset', 0);

        if ($limit > 0) {
            $query .= " LIMIT ? OFFSET ?";
            $bindings[] = $limit;
            $bindings[] = $offset;
        }

        $rawUsers = \Illuminate\Support\Facades\DB::select($query, $bindings);

        $formattedUsers = [];
        foreach ($rawUsers as $user) {
            // Clean phone for WhatsApp Graph API: numbers only (remove +, -, spaces, etc.)
            $cleanPhone = preg_replace('/[^0-9]/', '', (string) $user->phone);

            $formattedUsers[] = [
                'id' => $user->id,
                'user_id' => $user->id,
                'name' => $user->cust_name,
                'cust_name' => $user->cust_name,
                'email' => $user->email,
                'phone' => $cleanPhone,
                'phone_number' => $cleanPhone,
                'phone_raw' => $user->phone,
                'stage' => $user->stage,
                'previous_stage' => $user->previous_stage,
                'stage_entered_date' => $user->stage_entered_date,
                'web_sort_name' => $user->web_sort_name,
                'country' => $user->country,
            ];
        }

        // Support direct array format for n8n Split In Batches loops
        if ($request->input('format') === 'array' || $request->boolean('raw_array') || $request->input('raw') == '1') {
            return response()->json($formattedUsers, 200);
        }

        return response()->json([
            'status' => '1',
            'message' => 'Users retrieved successfully',
            'date' => $targetDate,
            'total' => count($formattedUsers),
            'data' => $formattedUsers
        ], 200);
    }

    /**
     * Send WhatsApp stage messages via Freshchat API
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function send_stage_whatsapp(Request $request)
    {
        $token = $request->header('token') ?: $request->bearerToken() ?: $request->input('token');
        $validTokens = [
            '8f4d9b2e1a3c7f605d8e2b9c4a1f3b7d',
            '1e4e20745582f33c8733ea71f54cf21e',
            'b371190226343542279188e4428a2a72'
        ];

        if (!in_array($token, $validTokens)) {
            return response()->json([
                'status' => '0',
                'message' => 'Unauthorized: Invalid token'
            ], 401);
        }

        // Validate recipient phone
        $phone = $request->input('phone') ?: $request->input('phone_number') ?: $request->input('sendTo');
        if (empty($phone)) {
            return response()->json([
                'status' => '0',
                'message' => 'Recipient phone number is required'
            ], 400);
        }

        // Validate template or stage
        $template = $request->input('template') ?: $request->input('stage');
        if (empty($template)) {
            return response()->json([
                'status' => '0',
                'message' => 'Template name or stage is required'
            ], 400);
        }

        // Map stage to template if stage name is provided
        $stageMap = [
            'dormant' => 'dormant_clients',
            'inactive' => 'inactive_clients',
            'unconverted' => 'unconverted_clients',
        ];
        $templateLower = strtolower(trim($template));
        if (isset($stageMap[$templateLower])) {
            $template = $stageMap[$templateLower];
        }

        // Validate website / web_sort_name
        $rawSite = $request->input('website') ?: $request->input('web_sort_name') ?: $request->input('site_sort_name') ?: $request->input('siteName') ?: 'GAH';
        $siteName = strtoupper(trim((string) $rawSite));
        $validSites = ['GAH', 'GAH_AU', 'IAH', 'IAH_AU', 'AP', 'AD'];
        if (!in_array($siteName, $validSites)) {
            if (str_contains($siteName, 'IAH_AU'))
                $siteName = 'IAH_AU';
            elseif (str_contains($siteName, 'GAH_AU'))
                $siteName = 'GAH_AU';
            elseif (str_contains($siteName, 'IAH'))
                $siteName = 'IAH';
            elseif (str_contains($siteName, 'GAH'))
                $siteName = 'GAH';
            elseif (str_contains($siteName, 'AD'))
                $siteName = 'AD';
            elseif (str_contains($siteName, 'AP'))
                $siteName = 'AP';
            else
                $siteName = 'GAH';
        }

        $name = $request->input('name') ?: $request->input('cust_name') ?: 'Customer';
        $userId = $request->input('user_id') ?: $request->input('id') ?: $request->input('userId') ?: $request->input('cust_id') ?: 0;

        $options = [
            'siteName' => $siteName,
            'sendTo' => $phone,
            'userId' => $userId,
            'name' => $name,
            'email' => $request->input('email', ''),
            'campaign_id' => $request->input('campaign_id'),
            'message' => $request->input('message', '')
        ];

        // Pass any additional template-specific fields
        foreach (['order_id', 'order_code', 'amount', 'words', 'topic', 'ddate', 'file', 'img', 'video', 'document', 'filename'] as $field) {
            if ($request->has($field)) {
                $options[$field] = $request->input($field);
            }
        }

        $res = send_whatsapp($template, $options);

        $isSuccess = ($res === true) || (is_array($res) && isset($res['status']) && $res['status'] == 1);

        if ($isSuccess) {
            return response()->json([
                'status' => '1',
                'message' => is_array($res) ? ($res['message'] ?? 'WhatsApp message sent successfully') : 'WhatsApp message sent successfully',
                'request_id' => is_array($res) ? ($res['request_id'] ?? null) : null,
                'data' => [
                    'recipient' => $phone,
                    'website' => $siteName,
                    'template' => $template,
                    'user_id' => $userId,
                    'details' => is_array($res) ? ($res['data'] ?? []) : []
                ]
            ], 200);
        } else {
            return response()->json([
                'status' => '0',
                'message' => is_array($res) ? ($res['message'] ?? 'Failed to send WhatsApp message') : 'Failed to send WhatsApp message',
                'data' => is_array($res) ? $res : []
            ], 400);
        }
    }

    /**
     * Query users with stage_entered_date from user_logs
     *
     * @param Request $request
     * @return array
     */
    protected function getUsersData(Request $request)
    {
        $email = $request->input('email');
        $phone = $request->input('phone') ?: $request->input('phone_no') ?: $request->input('phone_number');
        $stage = $request->input('stage') ?: $request->input('stages');
        $leadSource = $request->input('lead_source');
        $created = $request->input('created') ?: $request->input('created_date') ?: $request->input('created_at');
        $createdFrom = $request->input('created_from');
        $createdTo = $request->input('created_to');
        $stageEnteredDate = $request->input('stage_entered_date') ?: $request->input('stage_date');
        $stageEnteredFrom = $request->input('stage_entered_from');
        $stageEnteredTo = $request->input('stage_entered_to');
        $userId = $request->input('id') ?: $request->input('user_id');
        $website = $request->input('website') ?: $request->input('web_sort_name') ?: $request->input('site_sort_name');

        $query = "
            SELECT 
                u.id,
                u.cust_name,
                u.email,
                u.phone,
                u.stage,
                u.lead_source,
                u.created,
                u.web_sort_name,
                u.country,
                u.status,
                u.category,
                u.alternate_email,
                u.alternate_phone,
                u.rm_id,
                COALESCE(latest_log.changed_at, u.created) as stage_entered_date,
                latest_log.old_event as previous_stage
            FROM users u
            LEFT JOIN (
                SELECT ul.user_id, ul.new_event, ul.old_event, ul.changed_at
                FROM user_logs ul
                INNER JOIN (
                    SELECT user_id, MAX(id) as max_id
                    FROM user_logs
                    WHERE event_type = 'Stage'
                    GROUP BY user_id
                ) latest ON ul.id = latest.max_id
            ) latest_log ON latest_log.user_id = u.id
            WHERE 1=1
        ";

        $bindings = [];

        // Filter by user ID
        if (!empty($userId)) {
            $query .= " AND u.id = ?";
            $bindings[] = (int) $userId;
        }

        // Filter by email
        if (!empty($email) && $email !== 'null') {
            $query .= " AND TRIM(u.email) = ?";
            $bindings[] = trim($email);
        }

        // Filter by phone
        if (!empty($phone) && $phone !== 'null') {
            $rawPhone = trim($phone);
            $cleanDigits = preg_replace('/\D/', '', $rawPhone);
            $formattedPhone = $rawPhone;

            try {
                $phoneUtil = PhoneNumberUtil::getInstance();
                $numberProto = $phoneUtil->parse($rawPhone, null);
                $countryCode = $numberProto->getCountryCode();
                $nationalNumber = $numberProto->getNationalNumber();
                $formattedPhone = '+' . $countryCode . '-' . $nationalNumber;
            } catch (\Exception $e) {
                $formattedPhone = $rawPhone;
            }

            $phoneConditions = ['u.phone = ?', 'u.phone = ?'];
            $bindings[] = $rawPhone;
            $bindings[] = $formattedPhone;

            if (!empty($cleanDigits)) {
                $phoneConditions[] = 'u.phone LIKE ?';
                $bindings[] = '%' . $cleanDigits . '%';

                if (strlen($cleanDigits) >= 10) {
                    $last10 = substr($cleanDigits, -10);
                    $phoneConditions[] = 'u.phone LIKE ?';
                    $bindings[] = '%' . $last10 . '%';
                }
            }

            $query .= " AND (" . implode(' OR ', $phoneConditions) . ")";
        }

        // Filter by stage
        if (!empty($stage)) {
            if (is_array($stage)) {
                $stagesArray = array_filter(array_map('trim', $stage));
            } else {
                $stagesArray = array_filter(array_map('trim', explode(',', $stage)));
            }

            if (!empty($stagesArray)) {
                $placeholders = implode(',', array_fill(0, count($stagesArray), '?'));
                $query .= " AND u.stage IN ($placeholders)";
                $bindings = array_merge($bindings, $stagesArray);
            }
        }

        // Filter by lead_source
        if (!empty($leadSource)) {
            $query .= " AND u.lead_source = ?";
            $bindings[] = trim($leadSource);
        }

        // Filter by created date
        if (!empty($created)) {
            $createdStr = trim($created);
            if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $createdStr)) {
                $query .= " AND DATE(u.created) = ?";
                $bindings[] = $createdStr;
            } else {
                $query .= " AND DATE(u.created) = DATE(?)";
                $bindings[] = $createdStr;
            }
        }

        if (!empty($createdFrom)) {
            $query .= " AND DATE(u.created) >= ?";
            $bindings[] = trim($createdFrom);
        }

        if (!empty($createdTo)) {
            $query .= " AND DATE(u.created) <= ?";
            $bindings[] = trim($createdTo);
        }

        // Filter by stage_entered_date (from user_logs, fallback to u.created)
        if (!empty($stageEnteredDate)) {
            $stageDateStr = trim($stageEnteredDate);
            if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $stageDateStr)) {
                $query .= " AND DATE(COALESCE(latest_log.changed_at, u.created)) = ?";
                $bindings[] = $stageDateStr;
            } else {
                $query .= " AND DATE(COALESCE(latest_log.changed_at, u.created)) = DATE(?)";
                $bindings[] = $stageDateStr;
            }
        }

        if (!empty($stageEnteredFrom)) {
            $query .= " AND DATE(COALESCE(latest_log.changed_at, u.created)) >= ?";
            $bindings[] = trim($stageEnteredFrom);
        }

        if (!empty($stageEnteredTo)) {
            $query .= " AND DATE(COALESCE(latest_log.changed_at, u.created)) <= ?";
            $bindings[] = trim($stageEnteredTo);
        }

        // Filter by website / web_sort_name
        if (!empty($website)) {
            $query .= " AND u.web_sort_name = ?";
            $bindings[] = trim($website);
        }

        // Order by
        $orderBy = $request->input('order_by', 'id');
        $direction = strtolower($request->input('order_dir', $request->input('direction', 'desc'))) === 'asc' ? 'ASC' : 'DESC';

        $allowedSorts = [
            'id' => 'u.id',
            'created' => 'u.created',
            'stage_entered_date' => 'stage_entered_date',
            'stage' => 'u.stage',
            'cust_name' => 'u.cust_name',
            'email' => 'u.email',
        ];
        $sortColumn = $allowedSorts[$orderBy] ?? 'u.id';
        $query .= " ORDER BY {$sortColumn} {$direction}";

        // Pagination (if limit is provided, or default 50)
        $limit = $request->has('limit') ? (int) $request->input('limit') : 50;
        $page = (int) $request->input('page', 1);
        $offset = $request->has('offset') ? (int) $request->input('offset') : ($page > 1 ? ($page - 1) * $limit : 0);

        if ($limit > 0) {
            $query .= " LIMIT ? OFFSET ?";
            $bindings[] = $limit;
            $bindings[] = $offset;
        }

        return \Illuminate\Support\Facades\DB::select($query, $bindings);
    }

    /**
     * Get user details with stage_entered_date from user_logs
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getUser(Request $request)
    {
        $token = $request->header('token') ?: $request->bearerToken() ?: $request->input('token');
        $validTokens = [
            '8f4d9b2e1a3c7f605d8e2b9c4a1f3b7d',
            '1e4e20745582f33c8733ea71f54cf21e',
            'b371190226343542279188e4428a2a72'
        ];

        if (!empty($token) && !in_array($token, $validTokens)) {
            return response()->json([
                'status' => '0',
                'message' => 'Unauthorized: Invalid token'
            ], 401);
        }

        $rawUsers = $this->getUsersData($request);

        $formattedUsers = [];
        foreach ($rawUsers as $user) {
            $cleanPhone = preg_replace('/[^0-9]/', '', (string) $user->phone);

            $formattedUsers[] = [
                'id' => (int) $user->id,
                'user_id' => (int) $user->id,
                'name' => $user->cust_name,
                'cust_name' => $user->cust_name,
                'email' => $user->email,
                'phone' => $user->phone,
                'phone_number' => $user->phone,
                'phone_clean' => $cleanPhone,
                'stage' => $user->stage,
                'lead_source' => $user->lead_source,
                'created' => $user->created,
                'stage_entered_date' => $user->stage_entered_date,
                'previous_stage' => $user->previous_stage,
                'web_sort_name' => $user->web_sort_name,
                'country' => $user->country,
                'status' => $user->status,
                'category' => $user->category,
                'rm_id' => $user->rm_id,
            ];
        }

        // Support direct array format for n8n Split In Batches loops
        if ($request->input('format') === 'array' || $request->boolean('raw_array') || $request->input('raw') == '1') {
            return response()->json($formattedUsers, 200);
        }

        // Support single object format if explicitly requested
        if ($request->boolean('single') || $request->input('single') == '1' || $request->input('first') == '1') {
            return response()->json([
                'status' => !empty($formattedUsers) ? '1' : '0',
                'message' => !empty($formattedUsers) ? 'User retrieved successfully' : 'User not found',
                'data' => $formattedUsers[0] ?? null
            ], !empty($formattedUsers) ? 200 : 404);
        }

        return response()->json([
            'status' => '1',
            'message' => count($formattedUsers) > 0 ? 'User data retrieved successfully' : 'No users found matching criteria',
            'total' => count($formattedUsers),
            'data' => $formattedUsers,
            // 'user' => count($formattedUsers) === 1 ? $formattedUsers[0] : null
        ], 200);
    }

    /**
     * Send WhatsApp message with template_name to all users matching getUser criteria
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function sendWhatsappToUsers(Request $request)
    {
        $token = $request->header('token') ?: $request->bearerToken() ?: $request->input('token');
        $validTokens = [
            '8f4d9b2e1a3c7f605d8e2b9c4a1f3b7d',
            '1e4e20745582f33c8733ea71f54cf21e',
            'b371190226343542279188e4428a2a72'
        ];

        if (!empty($token) && !in_array($token, $validTokens)) {
            return response()->json([
                'status' => '0',
                'message' => 'Unauthorized: Invalid token'
            ], 401);
        }

        // Validate template_name
        $template = $request->input('template_name') ?: $request->input('template') ?: $request->input('templateName') ?: $request->input('stage');
        if (empty($template)) {
            return response()->json([
                'status' => '0',
                'message' => 'template_name is required'
            ], 400);
        }

        // Map stage to template if stage name is provided
        $stageMap = [
            'dormant' => 'dormant_clients',
            'inactive' => 'inactive_clients',
            'unconverted' => 'unconverted_clients',
        ];
        $templateLower = strtolower(trim($template));
        if (isset($stageMap[$templateLower])) {
            $template = $stageMap[$templateLower];
        }

        // Fetch users using the exact same filters as getUser
        $rawUsers = $this->getUsersData($request);

        if (empty($rawUsers)) {
            return response()->json([
                'status' => '0',
                'message' => 'No users found matching criteria to send WhatsApp message',
                'template' => $template,
                'total_users' => 0,
                'sent_count' => 0,
                'failed_count' => 0,
                'skipped_no_phone' => 0,
                'results' => []
            ], 200);
        }

        $isDryRun = $request->boolean('dry_run') || $request->input('dry_run') == '1';

        $results = [];
        $sentCount = 0;
        $failedCount = 0;
        $skippedCount = 0;

        $globalSiteOverride = $request->input('website') ?: $request->input('siteName') ?: $request->input('site_sort_name');

        foreach ($rawUsers as $user) {
            $cleanPhone = preg_replace('/[^0-9]/', '', (string) $user->phone);

            if (empty($cleanPhone)) {
                $skippedCount++;
                $results[] = [
                    'user_id' => $user->id,
                    'name' => $user->cust_name,
                    'email' => $user->email,
                    'phone' => $user->phone,
                    'status' => '0',
                    'message' => 'Skipped: User has no valid phone number'
                ];
                continue;
            }

            // Determine site name: override or user's web_sort_name
            $rawSite = $globalSiteOverride ?: $user->web_sort_name ?: 'GAH';
            $siteName = $this->resolveSiteName($rawSite);

            $options = [
                'siteName' => $siteName,
                'sendTo' => $user->phone,
                'userId' => $user->id,
                'name' => $user->cust_name ?: 'Customer',
                'email' => $user->email ?: '',
                'campaign_id' => $request->input('campaign_id'),
                'message' => $request->input('message', '')
            ];

            // Pass any additional template-specific fields
            foreach (['order_id', 'order_code', 'amount', 'words', 'topic', 'ddate', 'file', 'img', 'video', 'document', 'filename'] as $field) {
                if ($request->has($field)) {
                    $options[$field] = $request->input($field);
                }
            }

            if ($isDryRun) {
                $sentCount++;
                $results[] = [
                    'user_id' => $user->id,
                    'name' => $user->cust_name,
                    'email' => $user->email,
                    'phone' => $cleanPhone,
                    'website' => $siteName,
                    'status' => '1',
                    'message' => 'Dry run: Message simulated'
                ];
                continue;
            }

            try {
                $res = send_whatsapp($template, $options);
                $isSuccess = ($res === true) || (is_array($res) && isset($res['status']) && $res['status'] == 1);

                if ($isSuccess) {
                    $sentCount++;
                    $results[] = [
                        'user_id' => $user->id,
                        'name' => $user->cust_name,
                        'email' => $user->email,
                        'phone' => $cleanPhone,
                        'website' => $siteName,
                        'status' => '1',
                        'message' => is_array($res) ? ($res['message'] ?? 'Message sent successfully') : 'Message sent successfully',
                        'request_id' => is_array($res) ? ($res['request_id'] ?? null) : null
                    ];
                } else {
                    $failedCount++;
                    $results[] = [
                        'user_id' => $user->id,
                        'name' => $user->cust_name,
                        'email' => $user->email,
                        'phone' => $cleanPhone,
                        'website' => $siteName,
                        'status' => '0',
                        'message' => is_array($res) ? ($res['message'] ?? 'Failed to send WhatsApp message') : 'Failed to send WhatsApp message',
                        'data' => is_array($res) ? $res : []
                    ];
                }
            } catch (\Exception $e) {
                $failedCount++;
                $results[] = [
                    'user_id' => $user->id,
                    'name' => $user->cust_name,
                    'email' => $user->email,
                    'phone' => $cleanPhone,
                    'website' => $siteName,
                    'status' => '0',
                    'message' => $e->getMessage()
                ];
            }
        }

        return response()->json([
            'status' => $sentCount > 0 ? '1' : '0',
            'message' => $isDryRun ? 'Dry run simulation completed' : 'WhatsApp messages processing completed',
            'template' => $template,
            'total_users' => count($rawUsers),
            'sent_count' => $sentCount,
            'failed_count' => $failedCount,
            'skipped_no_phone' => $skippedCount,
            'results' => $results
        ], 200);
    }

    /**
     * Send WhatsApp template message to an array of users passed directly in data (from getUsers API)
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function sendWhatsappToUsersData(Request $request)
    {
        $token = $request->header('token') ?: $request->bearerToken() ?: $request->input('token');
        $validTokens = [
            '8f4d9b2e1a3c7f605d8e2b9c4a1f3b7d',
            '1e4e20745582f33c8733ea71f54cf21e',
            'b371190226343542279188e4428a2a72'
        ];

        if (!empty($token) && !in_array($token, $validTokens)) {
            return response()->json([
                'status' => '0',
                'message' => 'Unauthorized: Invalid token'
            ], 401);
        }

        // Validate template_name
        $template = $request->input('template_name');
        if (empty($template)) {
            return response()->json([
                'status' => '0',
                'message' => 'template_name is required'
            ], 400);
        }

        // Extract users data
        $usersData = $request->input('data');
        if (empty($usersData)) {
            $usersData = $request->input('users');
        }

        // If passed as JSON string (e.g. from multipart form or raw string)
        if (is_string($usersData)) {
            $decoded = json_decode($usersData, true);
            if (json_last_error() === JSON_ERROR_NONE) {
                $usersData = $decoded;
            }
        }

        // If the caller passed the full getUsers response object: {"status": "1", "data": [...]}
        if (is_array($usersData) && isset($usersData['data']) && is_array($usersData['data'])) {
            $usersData = $usersData['data'];
        }

        // If caller passed a single user object rather than a list
        if (is_array($usersData) && (isset($usersData['id']) || isset($usersData['phone']) || isset($usersData['email']))) {
            $usersData = [$usersData];
        }

        if (empty($usersData) || !is_array($usersData)) {
            return response()->json([
                'status' => '0',
                'message' => 'data parameter is required and must be a non-empty array of users (from getUsers API)',
                'template' => $template,
                'total_users' => 0,
                'sent_count' => 0,
                'failed_count' => 0,
                'skipped_no_phone' => 0,
                'results' => []
            ], 400);
        }

        $isDryRun = $request->boolean('dry_run') || $request->input('dry_run') == '1';

        $results = [];
        $sentCount = 0;
        $failedCount = 0;
        $skippedCount = 0;

        $globalSiteOverride = $request->input('website') ?: $request->input('siteName') ?: $request->input('site_sort_name');

        foreach ($usersData as $rawItem) {
            $item = (array) $rawItem;

            $userId = $item['id'] ?? $item['user_id'] ?? $item['userId'] ?? null;
            $userName = $item['name'] ?? $item['cust_name'] ?? $item['customer_name'] ?? 'Customer';
            $userEmail = $item['email'] ?? '';
            $rawPhone = $item['phone'] ?? $item['phone_number'] ?? $item['mobile'] ?? '';
            $cleanPhone = preg_replace('/[^0-9]/', '', (string) $rawPhone);

            if (empty($cleanPhone) || strlen($cleanPhone) < 6) {
                $skippedCount++;
                $results[] = [
                    'user_id' => $userId,
                    'name' => $userName,
                    'email' => $userEmail,
                    'phone' => $rawPhone,
                    'status' => '0',
                    'message' => 'Skipped: User has invalid or missing phone number'
                ];
                continue;
            }

            // Determine site name: override or user's web_sort_name
            $userSite = $item['web_sort_name'] ?? $item['website'] ?? $item['siteName'] ?? 'GAH';
            $rawSite = $globalSiteOverride ?: $userSite ?: 'GAH';
            $siteName = $this->resolveSiteName($rawSite);

            $options = [
                'siteName' => $siteName,
                'sendTo' => $rawPhone,
                'userId' => $userId,
                'name' => $userName ?: 'Customer',
                'email' => $userEmail ?: '',
                'campaign_id' => $request->input('campaign_id'),
                'message' => $request->input('message', '')
            ];

            // Pass any additional template-specific fields from request or item
            foreach (['order_id', 'order_code', 'amount', 'words', 'topic', 'ddate', 'file', 'img', 'video', 'document', 'filename'] as $field) {
                if ($request->has($field)) {
                    $options[$field] = $request->input($field);
                } elseif (isset($item[$field])) {
                    $options[$field] = $item[$field];
                }
            }

            if ($isDryRun) {
                $sentCount++;
                $results[] = [
                    'user_id' => $userId,
                    'name' => $userName,
                    'email' => $userEmail,
                    'phone' => $rawPhone,
                    'clean_phone' => $cleanPhone,
                    'website' => $siteName,
                    'status' => '1',
                    'message' => 'Dry run: Message simulated'
                ];
                continue;
            }

            try {
                $res = send_whatsapp($template, $options);
                $isSuccess = ($res === true) || (is_array($res) && isset($res['status']) && $res['status'] == 1);

                if ($isSuccess) {
                    $sentCount++;
                    $results[] = [
                        'user_id' => $userId,
                        'name' => $userName,
                        'email' => $userEmail,
                        'phone' => $rawPhone,
                        'clean_phone' => $cleanPhone,
                        'website' => $siteName,
                        'status' => '1',
                        'message' => is_array($res) ? ($res['message'] ?? 'Message sent successfully') : 'Message sent successfully',
                        'request_id' => is_array($res) ? ($res['request_id'] ?? null) : null
                    ];
                } else {
                    $failedCount++;
                    $results[] = [
                        'user_id' => $userId,
                        'name' => $userName,
                        'email' => $userEmail,
                        'phone' => $rawPhone,
                        'clean_phone' => $cleanPhone,
                        'website' => $siteName,
                        'status' => '0',
                        'message' => is_array($res) ? ($res['message'] ?? 'Failed to send WhatsApp message') : 'Failed to send WhatsApp message',
                        'data' => is_array($res) ? ($res['data'] ?? $res) : []
                    ];
                }
            } catch (\Exception $e) {
                $failedCount++;
                $results[] = [
                    'user_id' => $userId,
                    'name' => $userName,
                    'email' => $userEmail,
                    'phone' => $rawPhone,
                    'clean_phone' => $cleanPhone,
                    'website' => $siteName,
                    'status' => '0',
                    'message' => $e->getMessage()
                ];
            }
        }

        return response()->json([
            'status' => $sentCount > 0 ? '1' : '0',
            'message' => $isDryRun ? 'Dry run simulation completed' : 'WhatsApp messages processing completed',
            'template' => $template,
            'total_users' => count($usersData),
            'sent_count' => $sentCount,
            'failed_count' => $failedCount,
            'skipped_no_phone' => $skippedCount,
            'results' => $results
        ], 200);
    }

    /**
     * Send WhatsApp template message directly (fallback to request name and phone when data is empty)
     * or to an array of users passed in data
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function sendWhatsappDirect(Request $request)
    {
        $token = $request->header('token') ?: $request->bearerToken() ?: $request->input('token');
        $validTokens = [
            '8f4d9b2e1a3c7f605d8e2b9c4a1f3b7d',
            '1e4e20745582f33c8733ea71f54cf21e',
            'b371190226343542279188e4428a2a72'
        ];

        if (!empty($token) && !in_array($token, $validTokens)) {
            return response()->json([
                'status' => '0',
                'message' => 'Unauthorized: Invalid token'
            ], 401);
        }

        // Validate template_name
        $template = $request->input('template_name');
        if (empty($template)) {
            return response()->json([
                'status' => '0',
                'message' => 'template_name is required'
            ], 400);
        }

        // Extract users data
        $usersData = $request->input('data') ?: $request->data;
        if (empty($usersData)) {
            $usersData = $request->input('users') ?: $request->users;
        }

        // If passed as JSON string (e.g. from multipart form or raw string)
        if (is_string($usersData)) {
            $decoded = json_decode($usersData, true);
            if (json_last_error() === JSON_ERROR_NONE) {
                $usersData = $decoded;
            }
        }

        // If the caller passed the full getUsers response object: {"status": "1", "data": [...]}
        if (is_array($usersData) && isset($usersData['data']) && is_array($usersData['data'])) {
            $usersData = $usersData['data'];
        }

        // If caller passed a single user object rather than a list
        if (is_array($usersData) && (isset($usersData['id']) || isset($usersData['phone']) || isset($usersData['email']))) {
            $usersData = [$usersData];
        }

        // If data is empty, take name from $request->name and phone from $request->phone
        if (empty($usersData)) {
            $phone = $request->input('phone') ?: $request->phone;
            $name = $request->input('name') ?: $request->name;
            if (!empty($phone) || !empty($name)) {
                $displayName = ($name !== null && $name !== '') ? $name : 'Customer';
                if (is_array($phone)) {
                    $usersData = [];
                    foreach ($phone as $p) {
                        $usersData[] = [
                            'name' => $displayName,
                            'phone' => $p,
                            'email' => $request->input('email') ?: $request->email ?: '',
                            'id' => $request->input('id') ?: $request->id ?: null,
                        ];
                    }
                } else {
                    $usersData = [
                        [
                            'name' => $displayName,
                            'phone' => $phone,
                            'email' => $request->input('email') ?: $request->email ?: '',
                            'id' => $request->input('id') ?: $request->id ?: null,
                        ]
                    ];
                }
            }
        }

        if (empty($usersData) || !is_array($usersData)) {
            return response()->json([
                'status' => '0',
                'message' => 'data parameter is required and must be a non-empty array of users (from getUsers API) or phone number must be provided',
                'template' => $template,
                'total_users' => 0,
                'sent_count' => 0,
                'failed_count' => 0,
                'skipped_no_phone' => 0,
                'results' => []
            ], 400);
        }

        $isDryRun = $request->boolean('dry_run') || $request->input('dry_run') == '1';

        $results = [];
        $sentCount = 0;
        $failedCount = 0;
        $skippedCount = 0;

        $globalSiteOverride = $request->input('website') ?: $request->input('siteName') ?: $request->input('site_sort_name');

        foreach ($usersData as $rawItem) {
            $item = (array) $rawItem;

            $userId = $item['id'] ?? $item['user_id'] ?? $item['userId'] ?? null;
            $userName = $item['name'] ?? $item['cust_name'] ?? $item['customer_name'] ?? 'Customer';
            $userEmail = $item['email'] ?? '';
            $rawPhone = $item['phone'] ?? $item['phone_number'] ?? $item['mobile'] ?? '';
            $cleanPhone = preg_replace('/[^0-9]/', '', (string) $rawPhone);

            if (empty($cleanPhone) || strlen($cleanPhone) < 6) {
                $skippedCount++;
                $results[] = [
                    'user_id' => $userId,
                    'name' => $userName,
                    'email' => $userEmail,
                    'phone' => $rawPhone,
                    'status' => '0',
                    'message' => 'Skipped: User has invalid or missing phone number'
                ];
                continue;
            }

            // Determine site name: override or user's web_sort_name
            // $userSite = $item['web_sort_name'] ?? $item['website'] ?? $item['siteName'] ?? 'GAH';
            // $rawSite = $globalSiteOverride ?: $userSite ?: 'AD';
            $siteName = 'AD';

            $options = [
                'siteName' => $siteName,
                'sendTo' => $rawPhone,
                'userId' => $userId,
                'name' => $userName ?: 'Customer',
                'email' => $userEmail ?: '',
                'campaign_id' => $request->input('campaign_id'),
                'message' => $request->input('message', '')
            ];

            // Pass any additional template-specific fields from request or item
            foreach (['order_id', 'order_code', 'amount', 'words', 'topic', 'ddate', 'file', 'img', 'video', 'document', 'filename'] as $field) {
                if ($request->has($field)) {
                    $options[$field] = $request->input($field);
                } elseif (isset($item[$field])) {
                    $options[$field] = $item[$field];
                }
            }

            if ($isDryRun) {
                $sentCount++;
                $results[] = [
                    'user_id' => $userId,
                    'name' => $userName,
                    'email' => $userEmail,
                    'phone' => $rawPhone,
                    'clean_phone' => $cleanPhone,
                    'website' => $siteName,
                    'status' => '1',
                    'message' => 'Dry run: Message simulated'
                ];
                continue;
            }

            try {
                $res = send_whatsapp_AD($template, $options);
                $isSuccess = ($res === true) || (is_array($res) && isset($res['status']) && $res['status'] == 1);

                if ($isSuccess) {
                    $sentCount++;
                    $results[] = [
                        'user_id' => $userId,
                        'name' => $userName,
                        'email' => $userEmail,
                        'phone' => $rawPhone,
                        'clean_phone' => $cleanPhone,
                        'website' => $siteName,
                        'status' => '1',
                        'message' => is_array($res) ? ($res['message'] ?? 'Message sent successfully') : 'Message sent successfully',
                        'request_id' => is_array($res) ? ($res['request_id'] ?? null) : null
                    ];
                } else {
                    $failedCount++;
                    $results[] = [
                        'user_id' => $userId,
                        'name' => $userName,
                        'email' => $userEmail,
                        'phone' => $rawPhone,
                        'clean_phone' => $cleanPhone,
                        'website' => $siteName,
                        'status' => '0',
                        'message' => is_array($res) ? ($res['message'] ?? 'Failed to send WhatsApp message') : 'Failed to send WhatsApp message',
                        'data' => is_array($res) ? ($res['data'] ?? $res) : []
                    ];
                }
            } catch (\Exception $e) {
                $failedCount++;
                $results[] = [
                    'user_id' => $userId,
                    'name' => $userName,
                    'email' => $userEmail,
                    'phone' => $rawPhone,
                    'clean_phone' => $cleanPhone,
                    'website' => $siteName,
                    'status' => '0',
                    'message' => $e->getMessage()
                ];
            }
        }

        return response()->json([
            'status' => $sentCount > 0 ? '1' : '0',
            'message' => $isDryRun ? 'Dry run simulation completed' : 'WhatsApp messages processing completed',
            'template' => $template,
            'total_users' => count($usersData),
            'sent_count' => $sentCount,
            'failed_count' => $failedCount,
            'skipped_no_phone' => $skippedCount,
            'results' => $results
        ], 200);
    }

    /**
     * Resolve site name to standard valid sites
     *
     * @param string $rawSite
     * @return string
     */
    protected function resolveSiteName($rawSite)
    {
        $siteName = strtoupper(trim((string) $rawSite));
        $validSites = ['GAH', 'GAH_AU', 'IAH', 'IAH_AU', 'AP', 'AD'];
        if (in_array($siteName, $validSites)) {
            return $siteName;
        }
        if (str_contains($siteName, 'IAH_AU'))
            return 'IAH_AU';
        if (str_contains($siteName, 'GAH_AU'))
            return 'GAH_AU';
        if (str_contains($siteName, 'IAH'))
            return 'IAH';
        if (str_contains($siteName, 'GAH'))
            return 'GAH';
        if (str_contains($siteName, 'AD'))
            return 'AD';
        if (str_contains($siteName, 'AP'))
            return 'AP';
        return 'GAH';
    }

    /**
     * Get orders from tb_order filtered by order_id, order_code, order_source, customer_id, email, and order count
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getOrders(Request $request)
    {
        $token = $request->header('token') ?: $request->bearerToken() ?: $request->input('token');
        $validTokens = [
            '8f4d9b2e1a3c7f605d8e2b9c4a1f3b7d',
            '1e4e20745582f33c8733ea71f54cf21e',
            'b371190226343542279188e4428a2a72'
        ];

        if (!empty($token) && !in_array($token, $validTokens)) {
            return response()->json([
                'status' => '0',
                'message' => 'Unauthorized: Invalid token'
            ], 401);
        }

        $query = DB::table('tb_order')
            ->leftJoin('users', 'tb_order.cust_id', '=', 'users.id')
            ->select(
                'tb_order.id',
                'tb_order.order_code',
                'tb_order.cust_id as user_id',
                DB::raw('COALESCE(NULLIF(tb_order.customer_name, ""), users.cust_name) as customer_name'),
                DB::raw('COALESCE(NULLIF(tb_order.customer_email, ""), users.email) as customer_email'),
                DB::raw('COALESCE(NULLIF(tb_order.customer_phone, ""), users.phone) as customer_phone'),
                'tb_order.order_source',
                'tb_order.site_sort_name',
                'tb_order.cost',
                'tb_order.paid',
                'tb_order.due',
                'tb_order.curr_name as currency',
                'tb_order.topic',
                'tb_order.project_status',
                'tb_order.pay_status',
                'tb_order.create_date',
                'tb_order.ddate'
            )
            ->selectSub(function ($q) {
                $q->from('tb_order as sub')
                    ->where(function ($w) {
                        $w->where(function ($w1) {
                            $w1->whereNotNull('tb_order.cust_id')
                                ->where('tb_order.cust_id', '>', 0)
                                ->whereColumn('sub.cust_id', 'tb_order.cust_id');
                        })->orWhere(function ($w2) {
                            $w2->where(function ($w2a) {
                                $w2a->whereNull('tb_order.cust_id')
                                    ->orWhere('tb_order.cust_id', 0);
                            })
                                ->whereNotNull('tb_order.customer_email')
                                ->where('tb_order.customer_email', '!=', '')
                                ->whereColumn('sub.customer_email', 'tb_order.customer_email');
                        });
                    })
                    ->selectRaw('count(*)');
            }, 'customer_order_count');

        // Filter by order_id / id
        $orderId = $request->input('order_id') ?: $request->input('id');
        if (!empty($orderId)) {
            if (is_array($orderId)) {
                $query->whereIn('tb_order.id', $orderId);
            } elseif (str_contains($orderId, ',')) {
                $ids = array_filter(array_map('trim', explode(',', $orderId)));
                $query->whereIn('tb_order.id', $ids);
            } else {
                $query->where('tb_order.id', trim($orderId));
            }
        }

        // Filter by order_code
        $orderCode = $request->input('order_code') ?: $request->input('orderCode') ?: $request->input('code');
        if (!empty($orderCode)) {
            if (is_array($orderCode)) {
                $query->whereIn('tb_order.order_code', $orderCode);
            } elseif (str_contains($orderCode, ',')) {
                $codes = array_filter(array_map('trim', explode(',', $orderCode)));
                $query->whereIn('tb_order.order_code', $codes);
            } else {
                $query->where('tb_order.order_code', trim($orderCode));
            }
        }

        // Filter by order_source
        $orderSource = $request->input('order_source') ?: $request->input('source');
        if (!empty($orderSource)) {
            if (is_array($orderSource)) {
                $query->whereIn('tb_order.order_source', $orderSource);
            } elseif (str_contains($orderSource, ',')) {
                $sources = array_filter(array_map('trim', explode(',', $orderSource)));
                $query->whereIn('tb_order.order_source', $sources);
            } else {
                $query->where('tb_order.order_source', trim($orderSource));
            }
        }

        // Filter by customer_id / cust_id / user_id
        $customerId = $request->input('customer_id') ?: $request->input('cust_id') ?: $request->input('user_id');
        if (!empty($customerId)) {
            if (is_array($customerId)) {
                $query->where(function ($q) use ($customerId) {
                    $q->whereIn('tb_order.cust_id', $customerId)
                        ->orWhereIn('users.id', $customerId);
                });
            } elseif (is_string($customerId) && str_contains($customerId, ',')) {
                $cids = array_filter(array_map('trim', explode(',', $customerId)));
                $query->where(function ($q) use ($cids) {
                    $q->whereIn('tb_order.cust_id', $cids)
                        ->orWhereIn('users.id', $cids);
                });
            } else {
                $cleanId = is_string($customerId) ? trim($customerId) : $customerId;
                $query->where(function ($q) use ($cleanId) {
                    $q->where('tb_order.cust_id', $cleanId)
                        ->orWhere('users.id', $cleanId);
                });
            }
        }

        // Filter by email
        $email = $request->input('email') ?: $request->input('customer_email');
        if (!empty($email)) {
            if (is_array($email)) {
                $query->where(function ($q) use ($email) {
                    $q->whereIn('tb_order.customer_email', $email)
                        ->orWhereIn('users.email', $email);
                });
            } elseif (str_contains($email, ',')) {
                $emails = array_filter(array_map('trim', explode(',', $email)));
                $query->where(function ($q) use ($emails) {
                    $q->whereIn('tb_order.customer_email', $emails)
                        ->orWhereIn('users.email', $emails);
                });
            } else {
                $cleanEmail = trim($email);
                $query->where(function ($q) use ($cleanEmail) {
                    $q->where('tb_order.customer_email', $cleanEmail)
                        ->orWhere('users.email', $cleanEmail);
                });
            }
        }

        // Filter by order_count (customer total orders count in tb_order)
        $orderCount = $request->input('order_count') ?: $request->input('orderCount');
        if ($orderCount !== null && $orderCount !== '') {
            $orderCountStr = trim((string) $orderCount);
            if (preg_match('/^(>=|<=|>|<|!=|=)?\s*(\d+)$/', $orderCountStr, $matches)) {
                $operator = !empty($matches[1]) ? $matches[1] : '=';
                $val = (int) $matches[2];
                $query->having('customer_order_count', $operator, $val);
            }
        }
        if ($request->filled('min_order_count')) {
            $query->having('customer_order_count', '>=', (int) $request->input('min_order_count'));
        }
        if ($request->filled('max_order_count')) {
            $query->having('customer_order_count', '<=', (int) $request->input('max_order_count'));
        }

        // Optional filters
        if ($request->filled('website') || $request->filled('site_sort_name')) {
            $site = $request->input('website') ?: $request->input('site_sort_name');
            $query->where('tb_order.site_sort_name', trim($site));
        }
        if ($request->filled('project_status')) {
            $query->where('tb_order.project_status', trim($request->input('project_status')));
        }
        if ($request->filled('pay_status')) {
            $query->where('tb_order.pay_status', trim($request->input('pay_status')));
        }
        if ($request->filled('from_date')) {
            $query->where('tb_order.create_date', '>=', trim($request->input('from_date')) . ' 00:00:00');
        }
        if ($request->filled('to_date')) {
            $query->where('tb_order.create_date', '<=', trim($request->input('to_date')) . ' 23:59:59');
        }

        // Limit and Pagination
        $limit = (int) ($request->input('limit') ?: 50);
        if ($limit <= 0)
            $limit = 50;
        if ($limit > 500)
            $limit = 500;

        $offset = (int) ($request->input('offset') ?: 0);
        if ($request->filled('page') && (int) $request->input('page') > 1) {
            $offset = ((int) $request->input('page') - 1) * $limit;
        }

        $query->orderBy('tb_order.id', 'desc');

        $results = $query->offset($offset)->limit($limit)->get();

        $formattedOrders = [];
        foreach ($results as $order) {
            $formattedOrders[] = [
                'id' => $order->id,
                'order_id' => $order->id,
                'order_code' => $order->order_code,
                'user_id' => $order->user_id,
                'cust_id' => $order->user_id,
                'name' => $order->customer_name,
                'customer_name' => $order->customer_name,
                'email' => $order->customer_email,
                'customer_email' => $order->customer_email,
                'phone' => $order->customer_phone,
                'customer_phone' => $order->customer_phone,
                'order_source' => $order->order_source,
                'order_count' => (int) $order->customer_order_count,
                'customer_order_count' => (int) $order->customer_order_count,
                'site_sort_name' => $order->site_sort_name,
                'web_sort_name' => $order->site_sort_name,
                'cost' => $order->cost,
                'paid' => $order->paid,
                'due' => $order->due,
                'currency' => $order->currency,
                'topic' => $order->topic,
                'project_status' => $order->project_status,
                'pay_status' => $order->pay_status,
                'create_date' => $order->create_date,
                'ddate' => $order->ddate,
            ];
        }

        return response()->json([
            'status' => '1',
            'message' => count($formattedOrders) > 0 ? 'Orders retrieved successfully' : 'No orders found matching criteria',
            'order_count' => count($formattedOrders),
            'total' => count($formattedOrders),
            'data' => $formattedOrders
        ], 200);
    }
}

