<?php

namespace App\Http\Controllers\Admin;

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 CustomerVendorController extends Controller
{
    public function addcustomer()
    {
        $companyTypes = CompanyType::orderBy('companytype')->get();
        $accountTypes = AccountType::all();
        return view('admin.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('admin.customer.customerlist', compact('customers', 'columns'));
    }

    public function store(Request $request)
    {
        Log::info('admin - 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|digits:10',
            'secondary_mobile' => 'nullable|digits:10',
            '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:20',
            'iecno' => 'nullable|string|max:20',
            'billing_address' => 'nullable|string|max:500',
            'shipping_address' => 'nullable|string|max:500',
            'url' => 'nullable|url|max:255',
            'bank_name' => 'required|string|max:255',
            'branch_name' => 'required|string|max:255',
            'account_number' => 'required|string|max:20',
            'account_type' => 'required|string|max:255',
            'account_holder_name' => 'required|string|max:255',
            'account_currency' => 'nullable|string|max:10',
            'ifsc_code' => 'required|string|max:11',
            'swift_code' => 'nullable|string|max:20',

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

        if ($validator->fails()) {
            Log::error('admin - 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('admin - 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('admin - Customer/Vendor data saved', ['id' => $customerVendor->id]);

            if ($request->has('contacts')) {
                foreach ($request->contacts as $contact) {
                    ContactPerson::create([
                        'customer_vendor_id' => $customerVendor->id,
                        'name' => $contact['name'],
                        'email' => $contact['email'],
                        'mobile' => $contact['mobile'],
                        'designation' => $contact['designation'],
                    ]);
                    Log::info('admin - Contact person added', ['customer_vendor_id' => $customerVendor->id, 'contact' => $contact]);
                }
            }

            DB::commit();
            return redirect()->route('admin.customer.addcustomer')->with('success', 'Registration Successful!');
        } catch (\Exception $e) {
            DB::rollback();
            Log::error('admin - 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('admin.customer.customerview', compact('customer'));
    }

    public function edit($id)
    {
        $companyTypes = CompanyType::orderBy('companytype')->get();
        $accountTypes = AccountType::all();
        $customer = CustomerVendor::with('contactPersons')->findOrFail($id);
        return view('admin.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|digits:10',
            'secondary_mobile' => 'nullable|digits:10',
            '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' => 'required|string|max:255',
            'branch_name' => 'required|string|max:255',
            'account_number' => 'required|string|max:20',
            'account_type' => 'required|string|max:255',
            'account_holder_name' => 'required|string|max:255',
            'ifsc_code' => 'required|string|max:11',
            'image' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
            'contacts.*.name' => 'required|string|max:255',
            'contacts.*.email' => 'required|email|max:255',
            'contacts.*.mobile' => 'required|digits:10',
            '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) {
                    $customer->contactPersons()->create([
                        'name' => $contact['name'],
                        'email' => $contact['email'],
                        'mobile' => $contact['mobile'],
                        'designation' => $contact['designation'],
                    ]);
                }
            }

            DB::commit();
            return redirect()->route('admin.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');
        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])));

            // Adjust header fields to match the template exactly
            $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", // core fields
                // Now for contact person fields (allow up to 5 contacts)
                "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",
            ];

            if ($headerRow !== $expectedHeaders) {
                Log::error('Bulk customer import: header mismatch.', [
                    'provided' => $headerRow,
                    'expected' => $expectedHeaders
                ]);
                return back()->with('error', 'Invalid template format. Please use the provided sample template.');
            }

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

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

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

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

                // Validate main customer/vendor fields (simple, can extend as needed)
                $validator = Validator::make($rowData, [
                    'company_role' => 'required|in:Customer,Vendor,Both',
                    'company' => 'required|string|max:255',
                    'email' => 'required|email|unique:customer_vendors,email',
                    'mobile' => 'required|digits:10',
                    'secondary_mobile' => 'nullable|digits:10',
                    'company_type' => 'required|string|max:255',
                    'gstno' => 'required|string|max:20|unique:customer_vendors,gstno',
                    'panno' => 'required|string|max:10|unique:customer_vendors,panno',
                    'bank_name' => 'required|string|max:255',
                    'branch_name' => 'required|string|max:255',
                    'account_number' => 'required|string|max:20',
                    'account_type' => 'required|string|max:255',
                    'account_holder_name' => 'required|string|max:255',
                    'ifsc_code' => 'required|string|max:11',
                ]);

                if ($validator->fails()) {
                    $errorCount++;
                    $errorRows[] = "Row " . ($index + 1) . ": " . implode('; ', $validator->errors()->all());
                    continue;
                }

                try {
                    $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'],
                    ]);
                    // Contact persons (up to 5)
                    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++;
                    $errorRows[] = "Row " . ($index + 1) . ": " . $e->getMessage();
                    Log::error('Bulk customer import: DB insert failed.', [
                        'row_number' => $index + 1,
                        'exception' => $e->getMessage(),
                        'data' => $rowData
                    ]);
                }
            }
            DB::commit();

            $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()]);
            return back()->with('error', 'Failed to import: ' . $e->getMessage());
        }
    }
}
