<?php

namespace App\Http\Controllers;

use App\Models\CustomOrder;
use App\Models\CustomOrderFile;
use App\Models\CustomOrderSpecification;
use App\Models\CustomOrderProof;
use App\Models\AppSetting;
use App\Models\PrintStock;
use App\Events\OrderCreated;
use App\Events\DepositPaid;
use App\Events\ProofApproved;
use App\Events\ProofRevisionRequested;
use App\Events\BalancePaid;
use Illuminate\Http\Request;
use Illuminate\View\View;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Http;

class CustomOrderController extends Controller
{
    /**
     * Show custom orders index/list
     */
    public function index(): View
    {
        $customOrders = CustomOrder::where('user_id', auth()->id())
            ->orderBy('created_at', 'desc')
            ->get();

        return view('custom-orders.index', [
            'customOrders' => $customOrders,
        ]);
    }

    /**
     * Show custom order creation form
     */
    public function create(): View
    {
        $designFee = AppSetting::get('design_fee', 500);

        return view('custom-orders.create', [
            'printStocks' => PrintStock::all(),
            'designFee' => $designFee,
        ]);
    }

    /**
     * Store custom order and calculate quote
     */
    public function store(Request $request)
    {
        error_log('=== CUSTOM ORDER STORE METHOD CALLED (error_log) ===');
        error_log('Request method: ' . $request->method());
        error_log('Request path: ' . $request->path());
        error_log('Request all data: ' . json_encode($request->all()));
        $userId = auth()->id();
        error_log('User ID: ' . ($userId ?? 'NOT AUTHENTICATED'));
        
        Log::warning('=== CUSTOM ORDER STORE METHOD CALLED ===');
        Log::warning('Request all data', $request->all());
        Log::warning('User ID', ['user_id' => auth()->id()]);

        $validated = $request->validate([
            'type' => 'required|in:wallpaper,mural,fabric',
            'length' => 'nullable|numeric|min:0.1',
            'width' => 'nullable|numeric|min:0.1',
            'height' => 'nullable|numeric|min:0.1',
            'print_stock_id' => 'required|exists:print_stocks,id',
            'quantity' => 'required|integer|min:1',
            'customer_brief' => 'required|string|min:50|max:5000',
            'special_instructions' => 'nullable|string|max:1000',
            'library_discount' => 'boolean',
            'reference_images.*' => 'nullable|file|mimes:jpeg,png,jpg,gif,webp|max:5120',
        ]);

        Log::warning('Validation passed', $validated);

        // Get design fee from settings
        $designFee = AppSetting::get('design_fee', 500);
        $libraryDiscountApplied = $request->boolean('library_discount', false);

        // Deduct library discount if selected
        $finalDesignFee = $libraryDiscountApplied ? $designFee * 0.8 : $designFee;

        // Get print stock for material cost calculation
        $printStock = PrintStock::find($validated['print_stock_id']);

        // Calculate material cost based on type and dimensions
        $materialCost = $this->calculateMaterialCost(
            $validated['type'],
            $validated['length'] ?? 0,
            $validated['width'] ?? 0,
            $validated['height'] ?? 0,
            $validated['quantity'],
            $printStock
        );

        // Total cost = material cost + design fee
        $totalCost = $materialCost + $finalDesignFee;

        // Deposit is 20% of total, balance is 80%
        $depositAmount = $totalCost * 0.2;
        $balanceAmount = $totalCost * 0.8;

        // Create custom order
        $customOrder = CustomOrder::create([
            'user_id' => auth()->id(),
            'type' => $validated['type'],
            'design_fee' => $designFee,
            'library_discount_applied' => $libraryDiscountApplied,
            'material_cost' => $materialCost,
            'total_cost' => $totalCost,
            'deposit_amount' => $depositAmount,
            'balance_amount' => $balanceAmount,
            'customer_brief' => $validated['customer_brief'],
        ]);

        // Create specifications
        CustomOrderSpecification::create([
            'custom_order_id' => $customOrder->id,
            'length' => $validated['length'] ?? null,
            'width' => $validated['width'] ?? null,
            'height' => $validated['height'] ?? null,
            'print_stock_id' => $validated['print_stock_id'],
            'quantity' => $validated['quantity'],
            'special_instructions' => $validated['special_instructions'] ?? null,
        ]);

        // Handle file uploads
        if ($request->hasFile('reference_images')) {
            foreach ($request->file('reference_images') as $file) {
                $path = $file->store('custom-orders/references', 'local');

                CustomOrderFile::create([
                    'custom_order_id' => $customOrder->id,
                    'file_type' => 'reference_image',
                    'file_path' => $path,
                    'original_filename' => $file->getClientOriginalName(),
                    'file_size' => $file->getSize(),
                    'mime_type' => $file->getMimeType(),
                    'uploaded_by' => auth()->id(),
                ]);
            }
        }

        // Emit events for custom order creation with deposit
        OrderCreated::dispatch($customOrder, 'custom');

        return redirect()->route('custom-orders.show', $customOrder)->with('success', 'Custom order created successfully. Please review the quote and proceed with deposit payment.');
    }

    /**
     * Show custom order detail with quote
     */
    public function show(CustomOrder $customOrder): View
    {
        // Check authorization
        if ($customOrder->user_id !== auth()->id()) {
            abort(403);
        }

        return view('custom-orders.show', [
            'customOrder' => $customOrder,
        ]);
    }

    /**
     * Process deposit payment
     */
    public function depositPayment(Request $request)
    {
        Log::info('Deposit payment initiated', [
            'request_data' => $request->all(),
            'user_id' => auth()->id(),
        ]);
        $validated = $request->validate([
            'custom_order_id' => 'required|exists:custom_orders,id',
        ]);
        Log::info('Deposit payment validation passed', $validated);

        $customOrder = CustomOrder::findOrFail($validated['custom_order_id']);

        // Check authorization
        if ($customOrder->user_id !== auth()->id()) {
            Log::warning('Unauthorized deposit payment attempt', [
                'custom_order_id' => $customOrder->id,
                'user_id' => auth()->id(),
            ]);
            abort(403);
        }

        // Check if already paid
        if ($customOrder->deposit_status === 'paid') {
            Log::info('Deposit already paid for custom order', [
                'custom_order_id' => $customOrder->id,
            ]);
            return redirect()->route('custom-orders.show', $customOrder)
                ->with('info', 'Deposit already paid for this order.');
        }

        // Initiate Yoco payment for deposit
        Log::info('Initiating Yoco payment for custom order deposit', [
            'custom_order_id' => $customOrder->id,
            'deposit_amount' => $customOrder->deposit_amount,
        ]);
        $yocoResponse = $this->initiateYocoPayment(
            amount: (int)($customOrder->deposit_amount * 100), // Convert to cents
            customOrder: $customOrder,
            orderType: 'custom_deposit',
            description: "Deposit for Order #{$customOrder->order_number}"
        );

        if (!$yocoResponse) {
            Log::error('Failed to initiate Yoco payment for custom order deposit', [
                'custom_order_id' => $customOrder->id,
            ]);
            return redirect()->route('custom-orders.show', $customOrder)
                ->with('error', 'Failed to initiate payment. Please try again.');
        }
        Log::info('Yoco payment initiated successfully for custom order deposit', [
            'custom_order_id' => $customOrder->id,
            'checkout_url' => $yocoResponse['checkout_url'],
        ]);
        return redirect($yocoResponse['checkout_url']);
    }

    /**
     * Handle successful deposit payment
     */
    public function depositSuccess(CustomOrder $customOrder)
    {
        // Check authorization
        if ($customOrder->user_id !== auth()->id()) {
            abort(403);
        }

        // // Update order status
        // $customOrder->update([
        //     'deposit_status' => 'paid',
        //     'status' => 'submitted',
        // ]);

        return view('custom-orders.deposit-success', [
            'customOrder' => $customOrder,
        ]);
    }

    /**
     * Calculate material cost based on dimensions and print stock
     */
    private function calculateMaterialCost($type, $length, $width, $height, $quantity, $printStock)
    {
        $costPerUnit = $printStock->cost_per_meter ?? $printStock->cost_per_m2 ?? 0;

        if (!$costPerUnit) {
            return 0;
        }

        $cost = 0;

        if ($type === 'wallpaper' && $length > 0 && $width > 0) {
            // Area-based: length x width in meters
            $area = $length * $width;
            $cost = $area * $costPerUnit * $quantity;
        } elseif ($type === 'mural' && $width > 0 && $height > 0) {
            // Area-based: width x height in meters
            $area = $width * $height;
            $cost = $area * $costPerUnit * $quantity;
        } elseif ($type === 'fabric' && $length > 0) {
            // Linear: length in meters
            $cost = $length * $costPerUnit * $quantity;
        }

        return round($cost, 2);
    }

    /**
     * Initiate Yoco payment
     */
    private function initiateYocoPayment($amount, $customOrder, $orderType, $description)
    {
        
        Log::info('Initiating Yoco payment', [
            'order_id' => $customOrder->uuid,
            'order_type' => $orderType,
            'amount' => $amount,
            'description' => $description,
        ]);

        if (!$customOrder) {
            Log::error('Custom order not found for Yoco payment', [
                'order_id' => $customOrder->uuid ?? 'unknown',
            ]);
            return null;
        }
        Log::info('Custom order found for Yoco payment', [
            'order_id' => $customOrder->uuid,
            'custom_order_data' => $customOrder->toArray(),
        ]);
        // Get configuration
        $secretKey = config('services.yoco.secret_key');
        $mode = config('services.yoco.mode');

        Log::info('Yoco configuration', [
            'mode' => $mode,
            'secret_key_set' => !empty($secretKey) && $secretKey !== 'sk_test_your_key_here',
        ]);
        
        // Check if API key is configured
        if (empty($secretKey) || $secretKey === 'sk_test_your_key_here') {
            Log::error('Yoco secret key not configured');
            return null;
        }
        
        $baseUrl = $mode === 'live' 
            ? 'https://payments.yoco.com/api/checkouts'
            : 'https://payments.yoco.com/api/checkouts';
        
        $checkoutData = [
            'amount' => $amount,
            'currency' => 'ZAR',
            'successUrl' => route('yoco-custom-deposit-success', ['customOrder' => $customOrder->uuid]),
            'cancelUrl' => route('custom-orders.show', ['customOrder' => $customOrder->uuid]),
            'failureUrl' => route('custom-orders.show', ['customOrder' => $customOrder->uuid]),
            'metadata' => [
                'order_uuid' => $customOrder->uuid,
                'order_type' => $orderType,
                'site' => 'additional_design',
                'description' => $description
            ]
        ];

        Log::info('Yoco checkout data prepared', [
            'order_id' => $customOrder->uuid,
            'checkout_data' => $checkoutData,
        ]);
        
         // Make API request to Yoco
        
        try {
            $response = Http::withHeaders([
                'Authorization' => 'Bearer ' . $secretKey,
                'Content-Type' => 'application/json',
            ])->post($baseUrl, $checkoutData);
            
            if ($response->successful()) {
                $checkout = $response->json();
                
                $checkoutId = $checkout['id'] ?? null;
                $redirectUrl = $checkout['redirectUrl'] ?? null;
                
                Log::info('Yoco checkout created for custom order', [
                    'order_uuid' => $customOrder->uuid,
                    'checkout_id' => $checkoutId,
                    'redirect_url' => $redirectUrl,
                ]);
                
                if (!$checkoutId || !$redirectUrl) {
                    Log::error('Invalid Yoco checkout response: missing id or redirectUrl', [
                        'order_uuid' => $customOrder->uuid,
                        'response' => $checkout,
                    ]);
                    throw new \Exception('Invalid Yoco checkout response: missing id or redirectUrl');
                }
                
                // Persist checkout info to database
                try {
                    $customOrder->update([
                        'yoco_checkout_id' => $checkoutId,
                        'yoco_redirect_url' => $redirectUrl,
                        'yoco_checkout_response' => json_encode($checkout),
                    ]);
                    
                    // Reload the model to verify update
                    $customOrder->refresh();
                    
                    if ($customOrder->yoco_checkout_id) {
                        Log::info('Yoco checkout info saved successfully for custom order', [
                            'order_uuid' => $customOrder->uuid,
                            'yoco_checkout_id' => $customOrder->yoco_checkout_id,
                        ]);
                    } else {
                        Log::warning('Yoco checkout ID not saved after update for custom order', [
                            'order_uuid' => $customOrder->uuid,
                            'order_data' => $customOrder->toArray(),
                        ]);
                    }
                } catch (\Exception $dbException) {
                    Log::error('Database error while saving Yoco checkout info for custom order', [
                        'order_uuid' => $customOrder->uuid,
                        'error_message' => $dbException->getMessage(),
                        'error_code' => $dbException->getCode(),
                        'checkout_id' => $checkoutId,
                        'redirect_url' => $redirectUrl,
                    ]);
                    throw $dbException;
                }
                
                return [
                    'checkout_url' => $redirectUrl,
                    'checkout_id' => $checkoutId,
                ];
            } else {
                Log::error('Yoco API Error for custom order', [
                    'order_uuid' => $customOrder->uuid,
                    'status' => $response->status(),
                    'body' => $response->body()
                ]);
                return null;
            }
        } catch (\Exception $e) {
            Log::error('Yoco Payment Exception for custom order', [
                'order_uuid' => $customOrder->uuid,
                'message' => $e->getMessage()
            ]);
            return null;
        }
    }

    /**
     * Approve proof for custom order
     * 
     * POST /custom-orders/{id}/approve-proof
     */
    public function approveProof(Request $request, CustomOrder $customOrder)
    {
        // Authorization: only allow owner or admin
        if (auth()->user()->id !== $customOrder->user_id && !auth()->user()->is_admin) {
            abort(403, 'Unauthorized');
        }

        try {
            $customOrder->update([
                'proof_approved' => true,
                'proof_approved_at' => now(),
            ]);

            Log::info('Proof approved for custom order', [
                'custom_order_id' => $customOrder->id,
                'approved_by' => auth()->id(),
            ]);

            // Emit event
            ProofApproved::dispatch($customOrder);

            return response()->json([
                'success' => true,
                'message' => 'Proof approved successfully',
                'proof_approved_at' => $customOrder->proof_approved_at,
            ]);
        } catch (\Exception $e) {
            Log::error('Failed to approve proof', [
                'custom_order_id' => $customOrder->id,
                'error' => $e->getMessage(),
            ]);

            return response()->json([
                'error' => 'Failed to approve proof',
                'message' => $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Request proof revision for custom order
     * 
     * POST /custom-orders/{id}/request-changes
     */
    public function requestChanges(Request $request, CustomOrder $customOrder)
    {
        // Authorization: only allow owner or admin
        if (auth()->user()->id !== $customOrder->user_id && !auth()->user()->is_admin) {
            abort(403, 'Unauthorized');
        }

        $validated = $request->validate([
            'revision_notes' => 'required|string|min:10|max:1000',
        ]);

        try {
            $customOrder->update([
                'proof_approved' => false,
            ]);

            Log::info('Proof revision requested for custom order', [
                'custom_order_id' => $customOrder->id,
                'requested_by' => auth()->id(),
                'notes' => $validated['revision_notes'],
            ]);

            // Emit event
            ProofRevisionRequested::dispatch($customOrder, $validated['revision_notes']);

            return response()->json([
                'success' => true,
                'message' => 'Revision request sent successfully',
            ]);
        } catch (\Exception $e) {
            Log::error('Failed to request proof revision', [
                'custom_order_id' => $customOrder->id,
                'error' => $e->getMessage(),
            ]);

            return response()->json([
                'error' => 'Failed to request revision',
                'message' => $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Mark balance as paid for custom order
     * 
     * POST /custom-orders/{id}/pay-balance
     */
    public function markBalancePaid(Request $request, CustomOrder $customOrder)
    {
        // Authorization: only allow owner or admin
        if (auth()->user()->id !== $customOrder->user_id && !auth()->user()->is_admin) {
            abort(403, 'Unauthorized');
        }

        // Verify proof is approved before balance payment
        if (!$customOrder->proof_approved) {
            return response()->json([
                'error' => 'Proof must be approved before balance payment',
                'proof_approved' => $customOrder->proof_approved,
            ], 409);
        }

        try {
            $customOrder->update([
                'balance_status' => 'paid',
                'status' => 'printing',
            ]);

            Log::info('Balance paid for custom order', [
                'custom_order_id' => $customOrder->id,
                'marked_by' => auth()->id(),
            ]);

            // Emit event
            BalancePaid::dispatch($customOrder, $customOrder->balance_amount);

            return response()->json([
                'success' => true,
                'message' => 'Balance payment recorded successfully',
                'status' => $customOrder->status,
            ]);
        } catch (\Exception $e) {
            Log::error('Failed to mark balance paid', [
                'custom_order_id' => $customOrder->id,
                'error' => $e->getMessage(),
            ]);

            return response()->json([
                'error' => 'Failed to record balance payment',
                'message' => $e->getMessage(),
            ], 500);
        }
    }
}
