<?php

namespace App\Http\Controllers;

use App\Models\Contact;
use App\Services\CategoryPresetService;
use App\Models\ContactNote;
use App\Models\ContactHistory;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Concerns\ResolvesTenantHotel;
use Illuminate\Validation\Rule;

class ContactController extends Controller
{
    use ResolvesTenantHotel;

    private function getHotelId()
    {
        return $this->tenantHotelIdOrAbort();
    }

    /**
     * Display the vendors management page
     */
    public function indexView()
    {
        return view('vendors.index'); // Make sure this matches your blade file location
    }

    /**
     * API: Get all vendors with pagination and filtering
     */
    public function index(Request $request)
    {
        try {
            // Get query parameters
            $sort = $request->query('sort', 'name_asc');
            $search = $request->query('search', '');
            $perPage = $request->query('per_page', 10);
            $page = $request->query('page', 1);
            $limit = $request->query('limit', null);

            // Start building the query - ONLY VENDORS
            $query = Contact::where('type', 'vendor')
                ->where('hotel_id', $this->getHotelId())
                ->with('category');

            // Apply search filter
            if (!empty($search)) {
                $query->where(function($q) use ($search) {
                    $q->where('first_name', 'like', "%{$search}%")
                      ->orWhere('last_name', 'like', "%{$search}%")
                      ->orWhere('email', 'like', "%{$search}%")
                      ->orWhere('company', 'like', "%{$search}%")
                      ->orWhere('phone', 'like', "%{$search}%")
                      ->orWhereHas('category', function($q) use ($search) {
                          $q->where('name', 'like', "%{$search}%");
                      });
                });
            }

            // Apply sorting
            switch ($sort) {
                case 'name_desc':
                    $query->orderBy('company', 'desc');
                    break;
                case 'category':
                    $query->orderBy('category_id', 'asc')->orderBy('company', 'asc');
                    break;
                case 'recent':
                    $query->orderBy('created_at', 'desc');
                    break;
                case 'oldest':
                    $query->orderBy('created_at', 'asc');
                    break;
                case 'name_asc':
                default:
                    $query->orderBy('company', 'asc');
                    break;
            }

            // Handle limit for recent vendors (dashboard)
            if ($limit) {
                $vendors = $query->limit($limit)->get();
                return response()->json([
                    'contacts' => $vendors,
                    'total' => $vendors->count(),
                    'per_page' => $limit,
                    'current_page' => 1,
                    'last_page' => 1
                ]);
            }

            // Pagination for main table
            $vendors = $query->paginate($perPage, ['*'], 'page', $page);
            
            return response()->json([
                'contacts' => $vendors->items(),
                'total' => $vendors->total(),
                'per_page' => $vendors->perPage(),
                'current_page' => $vendors->currentPage(),
                'last_page' => $vendors->lastPage()
            ]);
            
        } catch (\Exception $e) {
            \Log::error('Error fetching vendors: ' . $e->getMessage());
            return response()->json([
                'error' => 'Failed to fetch vendors: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * API: Get all vendors (alias for index) - ADD THIS METHOD
     */
    public function getVendors(Request $request)
    {
        return $this->index($request);
    }

    /**
     * API: Get vendor statistics for dashboard
     */
    public function getVendorStats()
    {
        try {
            $totalVendors = Contact::where('type', 'vendor')->where('hotel_id', $this->getHotelId())->count();
            $activeVendors = Contact::where('type', 'vendor')->where('hotel_id', $this->getHotelId())->where('active', true)->count();
            
            return response()->json([
                'total_vendors' => $totalVendors,
                'active_vendors' => $activeVendors,
                'total_payables' => 0, // You can implement this later
                'overdue_invoices' => 0 // You can implement this later
            ]);
        } catch (\Exception $e) {
            \Log::error('Error fetching vendor stats: ' . $e->getMessage());
            return response()->json([
                'total_vendors' => 0,
                'active_vendors' => 0,
                'total_payables' => 0,
                'overdue_invoices' => 0
            ]);
        }
    }

    /**
     * API: Get a single vendor
     */
    public function show($id)
    {
        try {
            $vendor = Contact::where('type', 'vendor')
                ->where('hotel_id', $this->getHotelId())
                ->with('category')
                ->find($id);
            
            if (!$vendor) {
                return response()->json([
                    'error' => 'Vendor not found'
                ], 404);
            }
            
            return response()->json(['contact' => $vendor]);
        } catch (\Exception $e) {
            \Log::error('Error fetching vendor: ' . $e->getMessage());
            return response()->json([
                'error' => 'Vendor not found: ' . $e->getMessage()
            ], 404);
        }
    }

    /**
     * API: Create a new vendor
     */
    public function store(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'company' => 'required|string|max:255',
                'category_id' => [
                    'required',
                    Rule::exists('categories', 'id')->where(function ($query) {
                        $query->where('hotel_id', $this->getHotelId());
                    }),
                ],
                'first_name' => 'required|string|max:255',
                'last_name' => 'required|string|max:255',
                'email' => 'nullable|email|unique:contacts,email',
                'phone' => 'nullable|string|max:255',
                'address' => 'nullable|string',
                'city' => 'nullable|string|max:255',
                'country' => 'nullable|string|max:255',
                'payment_terms' => 'nullable|string|max:255',
                'bank_account' => 'nullable|string|max:255',
                'notes' => 'nullable|string',
                'active' => 'boolean'
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'message' => 'Validation failed',
                    'errors' => $validator->errors()
                ], 422);
            }

            DB::beginTransaction();

            // Create the vendor
            $vendor = Contact::create([
                'hotel_id' => $this->getHotelId(),
                'type' => 'vendor',
                'company' => $request->company,
                'category_id' => $request->category_id,
                'first_name' => $request->first_name,
                'last_name' => $request->last_name,
                'email' => $request->email,
                'phone' => $request->phone,
                'address' => $request->address,
                'city' => $request->city,
                'country' => $request->country,
                'payment_terms' => $request->payment_terms,
                'bank_account' => $request->bank_account,
                'notes' => $request->notes,
                'active' => $request->active ?? true,
            ]);

            // Add to history
            ContactHistory::create([
                'contact_id' => $vendor->id,
                'action' => 'Vendor created',
                'details' => 'New vendor created via system',
                'performed_by' => auth()->id() ?? 1,
            ]);

            DB::commit();

            return response()->json([
                'message' => 'Vendor created successfully',
                'contact' => $vendor->load('category')
            ], 201);
            
        } catch (\Exception $e) {
            DB::rollBack();
            \Log::error('Error creating vendor: ' . $e->getMessage());
            return response()->json([
                'error' => 'Failed to create vendor: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * API: Update a vendor
     */
    public function update(Request $request, $id)
    {
        try {
            $vendor = Contact::where('type', 'vendor')->where('hotel_id', $this->getHotelId())->find($id);
            
            if (!$vendor) {
                return response()->json([
                    'error' => 'Vendor not found'
                ], 404);
            }

            $validator = Validator::make($request->all(), [
                'company' => 'required|string|max:255',
                'category_id' => [
                    'required',
                    Rule::exists('categories', 'id')->where(function ($query) {
                        $query->where('hotel_id', $this->getHotelId());
                    }),
                ],
                'first_name' => 'required|string|max:255',
                'last_name' => 'required|string|max:255',
                'email' => 'nullable|email|unique:contacts,email,' . $id,
                'phone' => 'nullable|string|max:255',
                'address' => 'nullable|string',
                'city' => 'nullable|string|max:255',
                'country' => 'nullable|string|max:255',
                'payment_terms' => 'nullable|string|max:255',
                'bank_account' => 'nullable|string|max:255',
                'notes' => 'nullable|string',
                'active' => 'boolean'
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'message' => 'Validation failed',
                    'errors' => $validator->errors()
                ], 422);
            }

            DB::beginTransaction();

            $vendor->update([
                'company' => $request->company,
                'category_id' => $request->category_id,
                'first_name' => $request->first_name,
                'last_name' => $request->last_name,
                'email' => $request->email,
                'phone' => $request->phone,
                'address' => $request->address,
                'city' => $request->city,
                'country' => $request->country,
                'payment_terms' => $request->payment_terms,
                'bank_account' => $request->bank_account,
                'notes' => $request->notes,
                'active' => $request->active ?? $vendor->active,
            ]);

            // Add to history
            ContactHistory::create([
                'contact_id' => $vendor->id,
                'action' => 'Vendor updated',
                'details' => 'Vendor information was updated',
                'performed_by' => auth()->id() ?? 1,
            ]);

            DB::commit();

            return response()->json([
                'message' => 'Vendor updated successfully',
                'contact' => $vendor->load('category')
            ]);
            
        } catch (\Exception $e) {
            DB::rollBack();
            \Log::error('Error updating vendor: ' . $e->getMessage());
            return response()->json([
                'error' => 'Failed to update vendor: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * API: Delete a vendor
     */
    public function destroy($id)
    {
        try {
            $vendor = Contact::where('type', 'vendor')->where('hotel_id', $this->getHotelId())->find($id);
            
            if (!$vendor) {
                return response()->json([
                    'error' => 'Vendor not found'
                ], 404);
            }

            DB::beginTransaction();

            // Add to history before deleting
            ContactHistory::create([
                'contact_id' => $vendor->id,
                'action' => 'Vendor deleted',
                'details' => 'Vendor was deleted from the system',
                'performed_by' => auth()->id() ?? 1,
            ]);

            $vendor->delete();

            DB::commit();

            return response()->json([
                'message' => 'Vendor deleted successfully'
            ]);
            
        } catch (\Exception $e) {
            DB::rollBack();
            \Log::error('Error deleting vendor: ' . $e->getMessage());
            return response()->json([
                'error' => 'Failed to delete vendor: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * API: Get vendor categories
     */
    public function getVendorCategories()
    {
        try {
            $hotelId = $this->getHotelId();
            if (!$hotelId) {
                return response()->json(['categories' => [], 'preset_names' => []]);
            }

            $data = app(CategoryPresetService::class)->categoriesForDropdowns((int) $hotelId);

            return response()->json([
                'categories' => $data['categories'],
                'preset_names' => $data['preset_names'],
            ]);
        } catch (\Exception $e) {
            \Log::error('Error fetching vendor categories: ' . $e->getMessage());
            return response()->json(['error' => 'Failed to fetch categories'], 500);
        }
    }

    /**
     * Export vendors to CSV
     */
    public function export(Request $request)
    {
        try {
            $search = $request->query('search', '');
            $includeInactive = $request->query('include_inactive', true);

            $query = Contact::where('type', 'vendor')
                ->where('hotel_id', $this->getHotelId())
                ->with('category');

            if (!empty($search)) {
                $query->where(function($q) use ($search) {
                    $q->where('first_name', 'like', "%{$search}%")
                      ->orWhere('last_name', 'like', "%{$search}%")
                      ->orWhere('email', 'like', "%{$search}%")
                      ->orWhere('company', 'like', "%{$search}%");
                });
            }

            if (!$includeInactive) {
                $query->where('active', true);
            }

            $vendors = $query->orderBy('company', 'asc')->get();

            // Prepare CSV data
            $headers = [
                'Content-Type' => 'text/csv; charset=UTF-8',
                'Content-Disposition' => 'attachment; filename="vendors_export_' . date('Y-m-d_H-i-s') . '.csv"',
                'Pragma' => 'no-cache',
                'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
                'Expires' => '0'
            ];

            // Add BOM for UTF-8
            $bom = "\xEF\xBB\xBF";
            $csvData = $bom . "Company,Contact Person,Category,Email,Phone,Address,City,Country,Payment Terms,Bank Account,Status,Notes\n";

            foreach ($vendors as $vendor) {
                $csvData .= '"' . str_replace('"', '""', $vendor->company) . '",';
                $csvData .= '"' . str_replace('"', '""', $vendor->first_name . ' ' . $vendor->last_name) . '",';
                $csvData .= '"' . str_replace('"', '""', $vendor->category->name ?? 'N/A') . '",';
                $csvData .= '"' . str_replace('"', '""', $vendor->email ?? '') . '",';
                $csvData .= '"' . str_replace('"', '""', $vendor->phone ?? '') . '",';
                $csvData .= '"' . str_replace('"', '""', $vendor->address ?? '') . '",';
                $csvData .= '"' . str_replace('"', '""', $vendor->city ?? '') . '",';
                $csvData .= '"' . str_replace('"', '""', $vendor->country ?? '') . '",';
                $csvData .= '"' . str_replace('"', '""', $vendor->payment_terms ?? '') . '",';
                $csvData .= '"' . str_replace('"', '""', $vendor->bank_account ?? '') . '",';
                $csvData .= '"' . ($vendor->active ? 'Active' : 'Inactive') . '",';
                $csvData .= '"' . str_replace('"', '""', $vendor->notes ?? '') . '"';
                $csvData .= "\n";
            }

            return response($csvData, 200, $headers);

        } catch (\Exception $e) {
            \Log::error('Error exporting vendors: ' . $e->getMessage());
            return response()->json(['error' => 'Failed to export vendors'], 500);
        }
    }

    /**
     * Download import template
     */
    public function downloadTemplate()
    {
        $headers = [
            'Content-Type' => 'text/csv',
            'Content-Disposition' => 'attachment; filename="vendors_import_template.csv"',
        ];

        $template = "Company,First Name,Last Name,Category ID,Email,Phone,Address,City,Country,Payment Terms,Bank Account,Notes,Active\n";
        $template .= "ABC Supplies,John,Doe,1,john@abcsupplies.com,555-0123,123 Main St,New York,USA,Net 30,Bank of America,Good supplier,Yes\n";

        return response($template, 200, $headers);
    }

    /**
     * Import vendors from CSV
     */
    public function import(Request $request)
    {
        try {
            $request->validate([
                'file' => 'required|file|mimes:csv,txt|max:10240', // 10MB max
            ]);

            // This is a basic implementation - you'll want to expand this
            // to actually parse the CSV file and import the data
            $file = $request->file('file');
            
            // For now, return a success message
            return response()->json([
                'message' => 'Import functionality to be implemented',
                'stats' => [
                    'added' => 0,
                    'updated' => 0,
                    'skipped' => 0
                ]
            ]);

        } catch (\Exception $e) {
            \Log::error('Error importing vendors: ' . $e->getMessage());
            return response()->json(['error' => 'Failed to import vendors: ' . $e->getMessage()], 500);
        }
    }
}