<?php

namespace App\Http\Controllers;

use App\Models\Customer;
use App\Models\Employee;
use App\Models\FacebookIntegration;
use App\Models\Service;
use App\Models\ServiceSubscription;
use App\Services\EmployeeCommissionService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

class OneTimeServiceController extends Controller
{
    public function __construct()
    {
        $this->middleware('permission:services.one_time_service.view|pos.services.view')->only(['index', 'invoice']);
        $this->middleware('permission:services.one_time_service.create|pos.services.create')->only(['store']);
        $this->middleware('permission:services.one_time_service.update|pos.services.update')->only(['update']);
        $this->middleware('permission:services.one_time_service.delete')->only(['destroy']);
    }

    public function index(Request $request)
    {
        $service = Service::where('type', 'one_time_service')->first();

        if (! $service) {
            $service = Service::firstOrCreate(
                ['type' => 'one_time_service'],
                [
                    'name_ar' => 'خدمة لمرة واحدة (متابعة 3 أيام)',
                    'name_en' => 'One-time Service (3 days follow-up)',
                    'price' => 0,
                    'description_ar' => 'خدمة لمرة واحدة مع متابعة لمدة 3 أيام',
                    'description_en' => 'One-time service with 3 days follow-up',
                ]
            );
        }

        $query = ServiceSubscription::where('service_id', $service->id)->with(['creator', 'salesEmployee', 'customer']);

        if ($request->has('search') && ! empty($request->search)) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('invoice_number', 'like', "%{$search}%")
                    ->orWhereHas('customer', function ($customerQuery) use ($search) {
                        $customerQuery->where('name', 'like', "%{$search}%")
                            ->orWhere('phone', 'like', "%{$search}%")
                            ->orWhere('business_name', 'like', "%{$search}%");
                    });
            });
        }

        $subscriptions = $query->latest()->paginate(10)->appends($request->all());
        $employees = Auth::user()?->is_admin
            ? Employee::query()->where('is_active', true)->orderBy('full_name')->get(['id', 'full_name'])
            : null;

        if ($request->ajax()) {
            return view('services.one_time_service.partials.list', compact('subscriptions'))->render();
        }

        return view('services.one_time_service.index', compact('service', 'subscriptions', 'employees'));
    }

    public function store(Request $request, EmployeeCommissionService $commissionService)
    {
        $request->validate([
            'customer_name' => 'required|string|max:255',
            'phone' => 'required|string|max:255',
            'whatsapp' => 'required|string|max:255',
            'address' => 'required|string',
            'business_name' => 'required|string|max:255',
            'business_url' => 'nullable|url',
            'consultations_count' => 'nullable|integer|min:1|max:50',
            'price' => 'required|integer|min:0',
            'payment_method' => 'required|string',
            'sales_employee_id' => 'nullable|exists:employees,id',
        ]);

        if (! Schema::hasColumn('service_subscriptions', 'consultations_count')) {
            return back()->with('error', 'قاعدة البيانات غير محدثة. شغّل: php artisan migrate');
        }

        $service = Service::where('type', 'one_time_service')->firstOrFail();

        DB::beginTransaction();
        try {
            // 1. Create or find Customer first
            $customer = Customer::firstOrCreate(
                ['phone' => $request->phone],
                [
                    'name' => $request->customer_name,
                    'whatsapp' => $request->whatsapp,
                    'address' => $request->address,
                    'business_name' => $request->business_name,
                    'business_link' => $request->business_url,
                    'created_by' => Auth::id(),
                ]
            );

            // Generate Invoice Number
            $invoiceNumber = ServiceSubscription::generateNextInvoiceNumber();
            $defaultSalesEmployeeId = Employee::query()->where('user_id', Auth::id())->value('id');
            $salesEmployeeId = Auth::user()?->is_admin && $request->filled('sales_employee_id')
                ? (int) $request->input('sales_employee_id')
                : $defaultSalesEmployeeId;

            // Create Subscription
            $subscription = ServiceSubscription::create([
                'service_id' => $service->id,
                'customer_id' => $customer->id,
                'invoice_number' => $invoiceNumber,
                'price' => $request->price,
                'payment_method' => $request->payment_method,
                'consultations_count' => (int) ($request->input('consultations_count') ?: 1),
                'created_by' => Auth::id(),
                'sales_employee_id' => $salesEmployeeId,
            ]);

            // Create Facebook Integration Record
            FacebookIntegration::firstOrCreate(
                ['customer_id' => $customer->id],
                [
                    'service_type' => 'one_time_service',
                    'assigned_employee_id' => Auth::id(),
                    'connection_status' => 'pending_connection',
                ]
            );

            $commissionService->createSalesCommissionForSubscription($subscription, (int) Auth::id());

            DB::commit();

            return redirect()->route('services.one_time_service.index')
                ->with('success', __('messages.subscription_added_success'));

        } catch (\Exception $e) {
            DB::rollBack();

            return back()->with('error', __('messages.error_occurred').': '.$e->getMessage());
        }
    }

    public function update(Request $request, $id, EmployeeCommissionService $commissionService)
    {
        $subscription = ServiceSubscription::findOrFail($id);

        $request->validate([
            'customer_name' => 'required|string|max:255',
            'phone' => 'required|string|max:255',
            'whatsapp' => 'required|string|max:255',
            'address' => 'required|string',
            'business_name' => 'required|string|max:255',
            'business_url' => 'nullable|url',
            'consultations_count' => 'nullable|integer|min:1|max:50',
            'price' => 'required|integer|min:0',
            'payment_method' => 'required|string',
            'sales_employee_id' => 'nullable|exists:employees,id',
        ]);

        if (! Schema::hasColumn('service_subscriptions', 'consultations_count')) {
            return back()->with('error', 'قاعدة البيانات غير محدثة. شغّل: php artisan migrate');
        }

        DB::beginTransaction();
        try {
            $customerPayload = [
                'name' => $request->customer_name,
                'phone' => $request->phone,
                'whatsapp' => $request->whatsapp,
                'address' => $request->address,
                'business_name' => $request->business_name,
                'business_link' => $request->business_url,
            ];

            $customer = $subscription->customer;
            if ($customer) {
                $customer->update($customerPayload);
            } else {
                $customer = Customer::create(array_merge($customerPayload, ['created_by' => Auth::id()]));
                $subscription->customer()->associate($customer);
                $subscription->save();
            }

            $subscriptionPayload = [
                'price' => $request->price,
                'payment_method' => $request->payment_method,
                'consultations_count' => (int) ($request->input('consultations_count') ?: 1),
            ];

            if (Auth::user()?->is_admin) {
                $subscriptionPayload['sales_employee_id'] = $request->input('sales_employee_id') ?: $subscription->sales_employee_id;
            }

            $subscription->update($subscriptionPayload);
            $commissionService->createSalesCommissionForSubscription($subscription->refresh(), (int) $subscription->created_by);

            DB::commit();

            return redirect()->route('services.one_time_service.index')
                ->with('success', __('messages.subscription_updated_success'));
        } catch (\Exception $e) {
            DB::rollBack();

            return back()->with('error', __('messages.error_occurred').': '.$e->getMessage());
        }
    }

    public function destroy($id)
    {
        $subscription = ServiceSubscription::findOrFail($id);
        $subscription->delete();

        return redirect()->route('services.one_time_service.index')
            ->with('success', __('messages.subscription_deleted_success'));
    }

    public function invoice($id)
    {
        app()->setLocale('en');

        $subscription = ServiceSubscription::with('service')->findOrFail($id);

        // Generate Barcode SVG
        $barcode = $this->generateBarcodeSVG($subscription->invoice_number);

        return view('services.one_time_service.invoice', compact('subscription', 'barcode'));
    }

    private function generateBarcodeSVG($code)
    {
        // Code 39 Generator
        $code = strtoupper($code);
        $displayCode = $code;
        $code = '*'.$code.'*'; // Start and stop characters

        // B = Wide Bar, b = Narrow Bar, W = Wide Space, w = Narrow Space
        $barcodeTable = [
            '0' => 'bwbWBwBwb', '1' => 'BwbWbwbwB', '2' => 'bwBWbwbwB', '3' => 'BwBWbwbwb',
            '4' => 'bwbWBwbwB', '5' => 'BwbWBwbwb', '6' => 'bwBWBwbwb', '7' => 'bwbWbwBwB',
            '8' => 'BwbWbwBwb', '9' => 'bwBWbwBwb', 'A' => 'BwbwbWbwB', 'B' => 'bwBwbWbwB',
            'C' => 'BwBwbWbwb', 'D' => 'bwbwBWbwB', 'E' => 'BwbwBWbwb', 'F' => 'bwBwBWbwb',
            'G' => 'bwbwbWBwB', 'H' => 'BwbwbWBwb', 'I' => 'bwBwbWBwb', 'J' => 'bwbwBWBwb',
            'K' => 'BwbwbwbWB', 'L' => 'bwBwbwbWB', 'M' => 'BwBwbwbWb', 'N' => 'bwbwBwbWB',
            'O' => 'BwbwBwbWb', 'P' => 'bwBwBwbWb', 'Q' => 'bwbwbwBWB', 'R' => 'BwbwbwBWb',
            'S' => 'bwBwbwBWb', 'T' => 'bwbwBwBWb', 'U' => 'BWbwbwbwB', 'V' => 'bWBwbwbwB',
            'W' => 'BWBwbwbwb', 'X' => 'bWbwBwbwB', 'Y' => 'BWbwBwbwb', 'Z' => 'bWBwBwbwb',
            '-' => 'bWbwbwBwB', '.' => 'BWbwbwBwb', ' ' => 'bWBwbwBwb', '*' => 'bWbwBwBwb',
            '$' => 'bWbWbWbwb', '/' => 'bWbWbwbWb', '+' => 'bWbwbWbWb', '%' => 'bwbWbWbWb',
        ];

        $bars = [];

        // Config
        $narrow = 1.5;
        $wide = 4;
        $gap = 1.5; // Inter-character gap

        $currentX = 10;

        for ($i = 0; $i < strlen($code); $i++) {
            $char = $code[$i];
            if (! isset($barcodeTable[$char])) {
                continue;
            }

            $pattern = $barcodeTable[$char];
            for ($j = 0; $j < 9; $j++) {
                $isBar = ($j % 2 == 0);
                $type = $pattern[$j];

                $width = (strtoupper($type) === $type) ? $wide : $narrow;

                if ($isBar) {
                    $bars[] = ['x' => $currentX, 'w' => $width];
                }

                $currentX += $width;
            }
            $currentX += $gap;
        }

        $totalWidth = $currentX + 10;
        $height = 50;

        $svg = '<svg xmlns="http://www.w3.org/2000/svg" width="'.$totalWidth.'" height="'.$height.'" viewBox="0 0 '.$totalWidth.' '.$height.'">';
        $svg .= '<rect x="0" y="0" width="'.$totalWidth.'" height="'.$height.'" fill="white"/>';

        foreach ($bars as $bar) {
            $svg .= '<rect x="'.$bar['x'].'" y="5" width="'.$bar['w'].'" height="40" fill="black"/>';
        }

        $svg .= '</svg>';

        return $svg;
    }
}
