<?php

namespace App\Http\Controllers\SuperAdmin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\CustomerVendor;
use App\Models\ContactPerson;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Storage;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use App\Models\CompanyType;
use App\Models\AccountType;

class SuperAdminCustomerVendorController extends Controller
{
    public function addcustomer()
    {
        $companyTypes = CompanyType::orderBy('companytype')->get();
        $accountTypes = AccountType::all();
        return view('superadmin.customer.addcustomer', compact('companyTypes' , 'accountTypes'));
    }

    public function getAllCustomers()
    {
        $customers = CustomerVendor::with('contactPersons')->get();
        return response()->json($customers);
    }

    public function customerList()
    {
        // $customers = CustomerVendor::with('contactPersons')->orderBy('id')->get();
        $customers = CustomerVendor::with('contactPersons')->orderBy('id')->get();
        $columns = [
            'Company ID',
            'Image',
            'Company Name',
            'Company Acronym',
            'Company Email',
            'Official Contact Number',
            'secondary_mobile',
            'Company Type',
            'GST',
            'PAN',
            'MSME/Udyam',
            'IEC',
            'Website',
            'Billing address',
            'Shipping address',
            'Bank Name',
            'Bank Branch Name',
            'Account Number',
            'Account Type',
            'Account Holder Name',
            'Account Currency',
            'IFSC Code',
            'SWIFT/BIC Code',
            'Contact Person Name',
            'Contact Person Email',
            'Contact Person Mobile',
            'Contact Person Designation',
            'Status'
        ];
        return view('superadmin.customer.customerlist', compact('customers', 'columns'));
    }

    public function store(Request $request)
    {
        Log::info('SuperAdmin - Received request data:', $request->all());

        $validator = Validator::make($request->all(), [
            'company_role' => 'required|in:Customer,Vendor,Both',
            'company' => 'required|string|max:255',
            'email' => 'required|email|unique:customer_vendors,email',
            'company_nickname' => 'nullable|string|max:255',
            'image' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
            'mobile' => 'required',
            'secondary_mobile' => 'nullable',
            'company_type' => 'required|string|max:255',
            'gstno' => 'required|string|max:20|unique:customer_vendors,gstno',
            'panno' => 'required|string|max:10|unique:customer_vendors,panno',
            'msmeno' => 'nullable|string|max:255',
            'iecno' => 'nullable|string|max:255',
            'billing_address' => 'nullable|string|max:500',
            'shipping_address' => 'nullable|string|max:500',
            'url' => 'nullable|string|max:255',
            'bank_name' => 'nullable|string|max:255',
            'branch_name' => 'nullable|string|max:255',
            'account_number' => 'nullable|string|max:255',
            'account_type' => 'nullable|string|max:255',
            'account_holder_name' => 'nullable|string|max:255',
            'account_currency' => 'nullable|string|max:255',
            'ifsc_code' => 'nullable|string|max:255',
            'swift_code' => 'nullable|string|max:255',

            'contacts.*.name' => 'nullable|string|max:255',
            'contacts.*.email' => 'nullable|email|max:255',
            'contacts.*.mobile' => 'nullable',
            'contacts.*.designation' => 'nullable|string|max:255',
        ]);

        if ($validator->fails()) {
            Log::error('SuperAdmin - Validation failed:', $validator->errors()->toArray());
            return redirect()->back()->withErrors($validator)->withInput();
        }

        $logoPath = null;
        if ($request->hasFile('image')) {
            $logoPath = $request->file('image')->storeAs('logos', uniqid() . '.' . $request->file('image')->getClientOriginalExtension(), 'public');
            Log::info('SuperAdmin - Logo uploaded successfully:', ['path' => $logoPath]);
        }

        try {
            DB::beginTransaction();

            $customerVendor = CustomerVendor::create([
                'company_role' => $request->company_role,
                'company' => $request->company,
                'email' => $request->email,
                'company_nickname' => $request->company_nickname,
                'image' => $logoPath,
                'mobile' => $request->mobile,
                'secondary_mobile' => $request->secondary_mobile,
                'company_type' => $request->company_type,
                'gstno' => $request->gstno,
                'panno' => $request->panno,
                'msmeno' => $request->msmeno,
                'iecno' => $request->iecno,
                'billing_address' => $request->billing_address,
                'shipping_address' => $request->shipping_address,
                'url' => $request->url,
                'bank_name' => $request->bank_name,
                'branch_name' => $request->branch_name,
                'account_number' => $request->account_number,
                'account_type' => $request->account_type,
                'account_holder_name' => $request->account_holder_name,
                'account_currency' => $request->account_currency ?? 'INR',
                'ifsc_code' => $request->ifsc_code,
                'swift_code' => $request->swift_code,
                'status' => 1,
            ]);
            Log::info('SuperAdmin - Customer/Vendor data saved', ['id' => $customerVendor->id]);

            if ($request->has('contacts')) {
                foreach ($request->contacts as $contact) {
                    // Only save contact if at least name or email or mobile is provided
                    if (!empty($contact['name']) || !empty($contact['email']) || !empty($contact['mobile'])) {
                        ContactPerson::create([
                            'customer_vendor_id' => $customerVendor->id,
                            'name' => $contact['name'] ?? null,
                            'email' => $contact['email'] ?? null,
                            'mobile' => $contact['mobile'] ?? null,
                            'designation' => $contact['designation'] ?? null,
                        ]);
                        Log::info('SuperAdmin - Contact person added', ['customer_vendor_id' => $customerVendor->id, 'contact' => $contact]);
                    }
                }
            }

            DB::commit();
            return redirect()->route('superadmin.customer.addcustomer')->with('success', 'Registration Successful!');
        } catch (\Exception $e) {
            DB::rollback();
            Log::error('SuperAdmin - Error occurred:', ['message' => $e->getMessage(), 'trace' => $e->getTraceAsString()]);
            return redirect()->back()->with('error', 'Something went wrong! ' . $e->getMessage());
        }
    }

    public function show($id)
    {
        $customer = CustomerVendor::with('contactPersons')->findOrFail($id);
        return view('superadmin.customer.customerview', compact('customer'));
    }

    public function edit($id)
    {
        $companyTypes = CompanyType::orderBy('companytype')->get();
        $accountTypes = AccountType::all();
        $customer = CustomerVendor::with('contactPersons')->findOrFail($id);
        return view('superadmin.customer.edit', compact('customer', 'companyTypes', 'accountTypes'));
    }

    public function update(Request $request, $id)
    {
        $customer = CustomerVendor::findOrFail($id);

        $request->validate([
            'company' => 'required|string|max:255',
            'company_role' => 'required|in:Customer,Vendor,Both',
            'email' => 'required|email|max:255|unique:customer_vendors,email,' . $customer->id,
            'mobile' => 'required',
            'secondary_mobile' => 'nullable',
            'company_type' => 'required|string|max:255',
            'gstno' => 'required|string|max:20|unique:customer_vendors,gstno,' . $customer->id,
            'panno' => 'required|string|max:10|unique:customer_vendors,panno,' . $customer->id,
            'bank_name' => 'nullable|string|max:255',
            'branch_name' => 'nullable|string|max:255',
            'account_number' => 'nullable|string|max:255',
            'account_type' => 'nullable|string|max:255',
            'account_holder_name' => 'nullable|string|max:255',
            'ifsc_code' => 'nullable|string|max:255',
            'image' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
            'contacts.*.name' => 'nullable|string|max:255',
            'contacts.*.email' => 'nullable|email|max:255',
            'contacts.*.mobile' => 'nullable',
            'contacts.*.designation' => 'nullable|string|max:255',
        ]);

        DB::beginTransaction();
        try {
            if ($request->hasFile('image')) {
                if ($customer->image && Storage::disk('public')->exists($customer->image)) {
                    Storage::disk('public')->delete($customer->image);
                }
                $logoPath = $request->file('image')->store('logos', 'public');
                $customer->image = $logoPath;
            }

            $customer->company = $request->company;
            $customer->company_nickname = $request->company_nickname;
            $customer->email = $request->email;
            $customer->mobile = $request->mobile;
            $customer->secondary_mobile = $request->secondary_mobile;
            $customer->company_role = $request->company_role;
            $customer->company_type = $request->company_type;
            $customer->gstno = $request->gstno;
            $customer->panno = $request->panno;
            $customer->msmeno = $request->msmeno;
            $customer->iecno = $request->iecno;
            $customer->billing_address = $request->billing_address;
            $customer->shipping_address = $request->shipping_address;
            $customer->url = $request->url;
            $customer->bank_name = $request->bank_name;
            $customer->branch_name = $request->branch_name;
            $customer->account_number = $request->account_number;
            $customer->account_type = $request->account_type;
            $customer->account_holder_name = $request->account_holder_name;
            $customer->account_currency = $request->account_currency ?? 'INR';
            $customer->ifsc_code = $request->ifsc_code;
            $customer->swift_code = $request->swift_code;
            $customer->save();

            $customer->contactPersons()->delete();

            if ($request->has('contacts')) {
                foreach ($request->contacts as $contact) {
                    // Only save contact if at least name or email or mobile is provided
                    if (!empty($contact['name']) || !empty($contact['email']) || !empty($contact['mobile'])) {
                        $customer->contactPersons()->create([
                            'name' => $contact['name'] ?? null,
                            'email' => $contact['email'] ?? null,
                            'mobile' => $contact['mobile'] ?? null,
                            'designation' => $contact['designation'] ?? null,
                        ]);
                    }
                }
            }

            DB::commit();
            return redirect()->route('superadmin.customer.customerlist')->with('success', 'Customer details updated successfully.');
        } catch (\Exception $e) {
            DB::rollback();
            return redirect()->back()->with('error', 'Something went wrong: ' . $e->getMessage());
        }
    }

    public function destroy($id)
    {
        $customer = CustomerVendor::findOrFail($id);
        // Optionally, delete logo and contacts
        if ($customer->image && Storage::disk('public')->exists($customer->image)) {
            Storage::disk('public')->delete($customer->image);
        }
        $customer->contactPersons()->delete();
        $customer->delete();
        return response()->json(['message' => 'Customer deleted successfully']);
    }
    public function importCustomers(Request $request)
{
    $request->validate([
        'excel_file' => 'required|file|mimes:xlsx',
    ]);

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

    Log::info('Bulk customer import initiated.', [
        'filename' => $file->getClientOriginalName(),
        'user_id' => auth()->id(),
        'timestamp' => now()->toDateTimeString(),
    ]);

    try {
        $spreadsheet = IOFactory::load($file->getRealPath());
        $worksheet = $spreadsheet->getActiveSheet();
        $rows = $worksheet->toArray(null, true, true, true);
        $headerRow = array_map('strtolower', array_map('trim', array_values($rows[1])));

        $expectedHeaders = [
            "company_role", "company", "company_nickname", "email", "mobile", "secondary_mobile",
            "company_type", "gstno", "panno", "msmeno", "iecno", "billing_address", "shipping_address",
            "url", "bank_name", "branch_name", "account_number", "account_type", "account_holder_name",
            "account_currency", "ifsc_code", "swift_code", "status",
            "contact_name_1", "contact_email_1", "contact_mobile_1", "contact_designation_1",
            "contact_name_2", "contact_email_2", "contact_mobile_2", "contact_designation_2",
            "contact_name_3", "contact_email_3", "contact_mobile_3", "contact_designation_3",
            "contact_name_4", "contact_email_4", "contact_mobile_4", "contact_designation_4",
            "contact_name_5", "contact_email_5", "contact_mobile_5", "contact_designation_5"
        ];

        $missingHeaders = array_diff($expectedHeaders, $headerRow);
        $extraHeaders = array_diff($headerRow, $expectedHeaders);

        if (!empty($missingHeaders) || !empty($extraHeaders)) {
            Log::error('Bulk customer import: header mismatch.', [
                'provided' => $headerRow,
                'expected' => $expectedHeaders,
                'missing' => $missingHeaders,
                'extra' => $extraHeaders,
            ]);
            return back()->with('error', 'Invalid template format. Missing or extra columns detected.');
        }

        $successCount = 0;
        $errorCount = 0;
        $errorRows = [];
        DB::beginTransaction();

        foreach (array_slice($rows, 1) as $index => $row) {
            if ($index == 0) continue;

            if (array_filter($row) === []) {
                Log::info("Row {$index} skipped: empty row.");
                continue;
            }

            $rowData = array_combine($expectedHeaders, array_map('trim', array_values($row)));

            $rowData['status'] = ($rowData['status'] === '1' || strtolower($rowData['status']) === 'active') ? 1 : 0;
            $rowData['account_currency'] = $rowData['account_currency'] ?: 'INR';

            // // Pre-checks for critical unique fields
            // if (empty($rowData['panno'])) {
            //     $errorCount++;
            //     $errorRows[] = "Row " . ($index + 1) . ": PAN number is required.";
            //     Log::warning('Validation failed: missing PAN.', [
            //         'row_index' => $index + 1,
            //         'row_data' => $rowData,
            //     ]);
            //     continue;
            // }

            // if (empty($rowData['email'])) {
            //     $errorCount++;
            //     $errorRows[] = "Row " . ($index + 1) . ": Email is required.";
            //     Log::warning('Validation failed: missing Email.', [
            //         'row_index' => $index + 1,
            //         'row_data' => $rowData,
            //     ]);
            //     continue;
            // }

            $validator = Validator::make($rowData, [
                'company_role' => 'required|in:Customer,Vendor,Both',
                'company' => 'required|string|max:255',
                'mobile' => 'nullable',
                'secondary_mobile' => 'nullable',
                'company_type' => 'required|string|max:255',
                'gstno' => 'nullable|string|max:20|unique:customer_vendors,gstno',
                'bank_name' => 'nullable|string|max:255',
                'branch_name' => 'nullable|string|max:255',
                'account_number' => 'nullable|string|max:255',
                'account_type' => 'nullable|string|max:255',
                'account_holder_name' => 'nullable|string|max:255',
                'ifsc_code' => 'nullable|string|max:255',
            ]);

            if ($validator->fails()) {
                $errorMessage = "Row " . ($index + 1) . ": " . implode('; ', $validator->errors()->all());
                Log::warning('Validation failed for row.', [
                    'row_index' => $index + 1,
                    'errors' => $validator->errors()->all(),
                    'row_data' => $rowData,
                ]);
                $errorCount++;
                $errorRows[] = $errorMessage;
                continue;
            }

            try {
                
                // Check for existing company (case-insensitive)
                $existingCompany = CustomerVendor::whereRaw('LOWER(TRIM(company)) = ?', [strtolower(trim($rowData['company']))])->exists();
            
                if ($existingCompany) {
                    $errorMessage = "Row " . ($index + 1) . ": Company '{$rowData['company']}' already exists. Skipping.";
                    Log::info($errorMessage);
                    $errorCount++;
                    $errorRows[] = $errorMessage;
                    continue;
                }
                $customer = CustomerVendor::create([
                    'company_role' => $rowData['company_role'],
                    'company' => $rowData['company'],
                    'company_nickname' => $rowData['company_nickname'],
                    'email' => $rowData['email'],
                    'mobile' => $rowData['mobile'],
                    'secondary_mobile' => $rowData['secondary_mobile'],
                    'company_type' => $rowData['company_type'],
                    'gstno' => $rowData['gstno'],
                    'panno' => $rowData['panno'],
                    'msmeno' => $rowData['msmeno'],
                    'iecno' => $rowData['iecno'],
                    'billing_address' => $rowData['billing_address'],
                    'shipping_address' => $rowData['shipping_address'],
                    'url' => $rowData['url'],
                    'bank_name' => $rowData['bank_name'],
                    'branch_name' => $rowData['branch_name'],
                    'account_number' => $rowData['account_number'],
                    'account_type' => $rowData['account_type'],
                    'account_holder_name' => $rowData['account_holder_name'],
                    'account_currency' => $rowData['account_currency'],
                    'ifsc_code' => $rowData['ifsc_code'],
                    'swift_code' => $rowData['swift_code'],
                    'status' => $rowData['status'],
                ]);

                Log::info("Customer/Vendor created successfully.", [
                    'id' => $customer->id,
                    'company' => $customer->company,
                    'email' => $customer->email,
                ]);

                for ($i = 1; $i <= 5; $i++) {
                    if (!empty($rowData["contact_name_$i"]) && !empty($rowData["contact_email_$i"]) && !empty($rowData["contact_mobile_$i"])) {
                        ContactPerson::create([
                            'customer_vendor_id' => $customer->id,
                            'name' => $rowData["contact_name_$i"],
                            'email' => $rowData["contact_email_$i"],
                            'mobile' => $rowData["contact_mobile_$i"],
                            'designation' => $rowData["contact_designation_$i"],
                        ]);
                    }
                }

                $successCount++;
            } catch (\Exception $e) {
                $errorCount++;
                $errorMessage = str_contains($e->getMessage(), 'Duplicate entry')
                    ? "Row " . ($index + 1) . ": Duplicate entry detected for a unique field."
                    : "Row " . ($index + 1) . ": " . $e->getMessage();

                $errorRows[] = $errorMessage;

                Log::error('Bulk customer import: DB insert failed.', [
                    'row_number' => $index + 1,
                    'exception' => $e->getMessage(),
                    'data' => $rowData
                ]);
            }
        }

        DB::commit();

        if ($successCount === 0 && $errorCount === 0) {
            Log::notice('Bulk import completed with no records processed.', [
                'filename' => $file->getClientOriginalName(),
                'row_count' => count($rows),
                'user_id' => auth()->id(),
            ]);
        }

        Log::info("Bulk import completed.", [
            'success_count' => $successCount,
            'error_count' => $errorCount,
            'file' => $file->getClientOriginalName(),
            'user_id' => auth()->id(),
            'timestamp' => now()->toDateTimeString(),
        ]);

        $message = "{$successCount} customers/vendors imported.";
        if ($errorCount > 0) {
            $message .= " {$errorCount} errors. See below.";
            return back()->with('success', $message)->with('errorRows', $errorRows);
        }

        return back()->with('success', $message);
    } catch (\Exception $e) {
        Log::critical('Bulk customer import failed.', [
            'exception' => $e->getMessage(),
            'user_id' => auth()->id(),
            'filename' => $file->getClientOriginalName(),
        ]);
        return back()->with('error', 'Failed to import: ' . $e->getMessage());
    }
}

}
