<?php

namespace App\Modules\Xero\Controllers;

use App\Http\Controllers\Controller;
use App\Modules\Xero\Services\XeroService;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Exception;

/**
 * Xero API Controller
 * 
 * Replaces the microservice at seraph.computerassistance.uk:5000
 * with direct Xero API integration using OAuth2
 */
class XeroApiController extends Controller
{
    protected $xeroService;
    
    public function __construct(XeroService $xeroService)
    {
        $this->xeroService = $xeroService;
    }
    
    /**
     * Get chart of accounts and items from Xero
     * Replaces: GET /api/items from microservice
     */
    public function getItems(Request $request): JsonResponse
    {
        try {
            $items = $this->xeroService->getItems();
            $accounts = $this->xeroService->getAccounts();
            
            // Combine items and accounts like the microservice did
            return response()->json([
                'success' => true,
                'data' => [
                    'items' => $items,
                    'accounts' => $accounts
                ]
            ]);
            
        } catch (Exception $e) {
            Log::error('Xero API Error - getItems: ' . $e->getMessage());
            
            return response()->json([
                'success' => false,
                'error' => 'Failed to fetch Xero items',
                'message' => $e->getMessage()
            ], 500);
        }
    }
    
    /**
     * Get chart of accounts from Xero
     * Replaces: Chart of accounts portion of /api/items
     */
    public function getAccounts(Request $request): JsonResponse
    {
        try {
            $accounts = $this->xeroService->getAccounts();
            
            return response()->json([
                'success' => true,
                'data' => $accounts
            ]);
            
        } catch (Exception $e) {
            Log::error('Xero API Error - getAccounts: ' . $e->getMessage());
            
            return response()->json([
                'success' => false,
                'error' => 'Failed to fetch Xero accounts',
                'message' => $e->getMessage()
            ], 500);
        }
    }
    
    /**
     * Get Xero types/categories
     * Replaces: GET /api/xero/type from microservice
     */
    public function getTypes(Request $request): JsonResponse
    {
        try {
            $types = $this->xeroService->getTypes();
            
            return response()->json([
                'success' => true,
                'data' => $types
            ]);
            
        } catch (Exception $e) {
            Log::error('Xero API Error - getTypes: ' . $e->getMessage());
            
            return response()->json([
                'success' => false,
                'error' => 'Failed to fetch Xero types',
                'message' => $e->getMessage()
            ], 500);
        }
    }
    
    /**
     * Create invoice in Xero
     * Replaces: POST /api/seraph/invoices/ from microservice
     */
    public function createInvoice(Request $request): JsonResponse
    {
        try {
            $invoiceData = $request->all();
            $xeroInvoice = $this->xeroService->createInvoice($invoiceData);
            
            return response()->json([
                'success' => true,
                'data' => $xeroInvoice,
                'xero_invoice_id' => $xeroInvoice['InvoiceID'] ?? null
            ]);
            
        } catch (Exception $e) {
            Log::error('Xero API Error - createInvoice: ' . $e->getMessage(), [
                'request_data' => $request->all()
            ]);
            
            return response()->json([
                'success' => false,
                'error' => 'Failed to create Xero invoice',
                'message' => $e->getMessage()
            ], 500);
        }
    }
    
    /**
     * Get invoice from Xero
     */
    public function getInvoice(Request $request, $id): JsonResponse
    {
        try {
            $invoice = $this->xeroService->getInvoice($id);
            
            return response()->json([
                'success' => true,
                'data' => $invoice
            ]);
            
        } catch (Exception $e) {
            Log::error('Xero API Error - getInvoice: ' . $e->getMessage());
            
            return response()->json([
                'success' => false,
                'error' => 'Failed to fetch Xero invoice',
                'message' => $e->getMessage()
            ], 500);
        }
    }
    
    /**
     * Update invoice in Xero
     */
    public function updateInvoice(Request $request, $id): JsonResponse
    {
        try {
            $invoiceData = $request->all();
            $xeroInvoice = $this->xeroService->updateInvoice($id, $invoiceData);
            
            return response()->json([
                'success' => true,
                'data' => $xeroInvoice
            ]);
            
        } catch (Exception $e) {
            Log::error('Xero API Error - updateInvoice: ' . $e->getMessage());
            
            return response()->json([
                'success' => false,
                'error' => 'Failed to update Xero invoice',
                'message' => $e->getMessage()
            ], 500);
        }
    }
    
    /**
     * Create purchase order in Xero
     * Replaces: POST /api/purchase/sync from microservice
     */
    public function createPurchaseOrder(Request $request): JsonResponse
    {
        try {
            $purchaseOrderData = $request->all();
            $xeroPurchaseOrder = $this->xeroService->createPurchaseOrder($purchaseOrderData);
            
            return response()->json([
                'success' => true,
                'data' => $xeroPurchaseOrder,
                'xero_purchase_order_id' => $xeroPurchaseOrder['PurchaseOrderID'] ?? null
            ]);
            
        } catch (Exception $e) {
            Log::error('Xero API Error - createPurchaseOrder: ' . $e->getMessage(), [
                'request_data' => $request->all()
            ]);
            
            return response()->json([
                'success' => false,
                'error' => 'Failed to create Xero purchase order',
                'message' => $e->getMessage()
            ], 500);
        }
    }
    
    /**
     * Get purchase order from Xero
     */
    public function getPurchaseOrder(Request $request, $id): JsonResponse
    {
        try {
            $purchaseOrder = $this->xeroService->getPurchaseOrder($id);
            
            return response()->json([
                'success' => true,
                'data' => $purchaseOrder
            ]);
            
        } catch (Exception $e) {
            Log::error('Xero API Error - getPurchaseOrder: ' . $e->getMessage());
            
            return response()->json([
                'success' => false,
                'error' => 'Failed to fetch Xero purchase order',
                'message' => $e->getMessage()
            ], 500);
        }
    }
    
    /**
     * Get contacts from Xero
     */
    public function getContacts(Request $request): JsonResponse
    {
        try {
            $contacts = $this->xeroService->getContacts();
            
            return response()->json([
                'success' => true,
                'data' => $contacts
            ]);
            
        } catch (Exception $e) {
            Log::error('Xero API Error - getContacts: ' . $e->getMessage());
            
            return response()->json([
                'success' => false,
                'error' => 'Failed to fetch Xero contacts',
                'message' => $e->getMessage()
            ], 500);
        }
    }
    
    /**
     * Create contact in Xero
     */
    public function createContact(Request $request): JsonResponse
    {
        try {
            $contactData = $request->all();
            $xeroContact = $this->xeroService->createContact($contactData);
            
            return response()->json([
                'success' => true,
                'data' => $xeroContact,
                'xero_contact_id' => $xeroContact['ContactID'] ?? null
            ]);
            
        } catch (Exception $e) {
            Log::error('Xero API Error - createContact: ' . $e->getMessage());
            
            return response()->json([
                'success' => false,
                'error' => 'Failed to create Xero contact',
                'message' => $e->getMessage()
            ], 500);
        }
    }
    
    /**
     * Get organization info from Xero
     */
    public function getOrganization(Request $request): JsonResponse
    {
        try {
            $organization = $this->xeroService->getOrganization();
            
            return response()->json([
                'success' => true,
                'data' => $organization
            ]);
            
        } catch (Exception $e) {
            Log::error('Xero API Error - getOrganization: ' . $e->getMessage());
            
            return response()->json([
                'success' => false,
                'error' => 'Failed to fetch Xero organization',
                'message' => $e->getMessage()
            ], 500);
        }
    }
    
    /**
     * Test Xero connection
     */
    public function testConnection(Request $request): JsonResponse
    {
        try {
            // First check if we have valid credentials
            $clientId = \App\Models\Setting::get('integrations.xero.client_id');
            $clientSecret = \App\Models\Setting::get('integrations.xero.client_secret');
            
            if (!$clientId || !$clientSecret) {
                throw new Exception('Xero credentials not configured. Please check Client ID and Secret.');
            }

            // Initialize OAuth flow
            $authService = app(\App\Modules\Xero\Services\XeroAuthService::class);
            
            // Try to get or create a system token
            try {
                $token = $authService->getValidToken();
                if (!$token) {
                    // Redirect to OAuth if no token
                    return response()->json([
                        'success' => false,
                        'needs_oauth' => true,
                        'auth_url' => $authService->getAuthorizationUrl(),
                        'message' => 'Please complete Xero authorization'
                    ]);
                }
            } catch (Exception $e) {
                // If token error, redirect to OAuth
                return response()->json([
                    'success' => false,
                    'needs_oauth' => true,
                    'auth_url' => $authService->getAuthorizationUrl(),
                    'message' => 'Please reconnect to Xero: ' . $e->getMessage()
                ]);
            }

            // Test the connection with the token
            $isConnected = $this->xeroService->testConnection();
            
            if (!$isConnected) {
                throw new Exception('Connection test failed. Please check your Xero settings.');
            }

            // Get organization details for verification
            $org = $this->xeroService->getOrganization();
            
            return response()->json([
                'success' => true,
                'connected' => true,
                'organization' => $org['Name'] ?? 'Unknown',
                'message' => 'Xero connection successful! Connected to: ' . ($org['Name'] ?? 'Unknown Organization')
            ]);
            
        } catch (Exception $e) {
            Log::error('Xero API Error - testConnection: ' . $e->getMessage());
            
            return response()->json([
                'success' => false,
                'connected' => false,
                'error' => 'Connection test failed',
                'message' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Sync bank accounts from Xero
     */
    public function syncBankAccounts(Request $request): JsonResponse
    {
        try {
            $bankAccounts = $this->xeroService->syncBankAccounts();
            
            return response()->json([
                'success' => true,
                'message' => 'Bank accounts synced successfully',
                'data' => $bankAccounts
            ]);
            
        } catch (Exception $e) {
            Log::error('Failed to sync bank accounts: ' . $e->getMessage());
            
            return response()->json([
                'success' => false,
                'error' => 'Failed to sync bank accounts',
                'message' => $e->getMessage()
            ], 500);
        }
    }
} 