<?php

namespace Modules\CRMCore\App\Http\Controllers;

use App\ApiClasses\Error;
use App\ApiClasses\Success;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Modules\CRMCore\App\Models\Company;
use Modules\CRMCore\App\Models\CustomerGroup;
use Modules\SystemCore\App\Enums\CustomerStatus;
use Modules\SystemCore\App\Enums\CustomerType;
use Modules\SystemCore\App\Models\CoreCustomer;
use Yajra\DataTables\Facades\DataTables;

class CustomerController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        $customerTypes = CustomerType::cases();
        $customerStatuses = CustomerStatus::cases();
        $companies = Company::where('is_active', true)->orderBy('name')->get();

        return view('crmcore::customers.index', compact('customerTypes', 'customerStatuses', 'companies'));
    }

    /**
     * Get data for DataTables
     */
    public function datatable(Request $request)
    {
        $query = CoreCustomer::with(['company', 'primaryContact', 'primaryAddress'])
            ->select('core_customers.*');

        // Apply filters
        if ($request->filled('customer_type')) {
            $query->where('customer_type', $request->customer_type);
        }

        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }

        if ($request->filled('is_active')) {
            $query->where('is_active', $request->is_active);
        }

        if ($request->filled('company_id')) {
            $query->where('company_id', $request->company_id);
        }

        return DataTables::of($query)
            ->addColumn('customer_name', function ($customer) {
                $initials = collect(explode(' ', $customer->name))
                    ->map(fn ($word) => strtoupper(substr($word, 0, 1)))
                    ->take(2)
                    ->implode('') ?: 'CU';

                $url = route('customers.show', $customer->id);

                return '
                    <div class="d-flex justify-content-start align-items-center user-name">
                        <div class="avatar-wrapper">
                            <div class="avatar avatar-sm me-3">
                                <span class="avatar-initial rounded-circle bg-label-primary">'.e($initials).'</span>
                            </div>
                        </div>
                        <div class="d-flex flex-column">
                            <a href="'.e($url).'" class="text-heading text-truncate">
                                <span class="fw-medium">'.e($customer->name).'</span>
                            </a>
                            <small class="text-muted">'.e($customer->customer_code ?? '').'</small>
                        </div>
                    </div>';
            })
            ->addColumn('contact_info', function ($customer) {
                $html = '';
                if ($customer->email) {
                    $html .= '<div><i class="bx bx-envelope text-muted me-1"></i>'.e($customer->email).'</div>';
                }
                if ($customer->phone) {
                    $html .= '<div><i class="bx bx-phone text-muted me-1"></i>'.e($customer->phone).'</div>';
                }

                return $html ?: '<span class="text-muted">-</span>';
            })
            ->addColumn('customer_type_badge', function ($customer) {
                $label = $customer->customer_type?->label() ?? __('Unknown');

                return '<span class="badge bg-primary">'.e($label).'</span>';
            })
            ->addColumn('company_name', function ($customer) {
                if ($customer->company) {
                    return '<a href="'.route('companies.show', $customer->company_id).'">'.e($customer->company->name).'</a>';
                }

                return '<span class="text-muted">-</span>';
            })
            ->addColumn('credit_limit_formatted', function ($customer) {
                return '<span class="fw-semibold">'.number_format($customer->credit_limit ?? 0, 2).'</span>';
            })
            ->addColumn('status_column', function ($customer) {
                if (! $customer->is_active) {
                    return '<span class="badge bg-secondary">'.__('Inactive').'</span>';
                }

                $label = $customer->status?->label() ?? __('Active');
                $color = $customer->status?->color() ?? 'success';

                return '<span class="badge bg-'.$color.'">'.e($label).'</span>';
            })
            ->addColumn('actions', function ($customer) {
                $actions = [
                    [
                        'label' => __('View'),
                        'icon' => 'bx bx-show',
                        'url' => route('customers.show', $customer->id),
                    ],
                    [
                        'label' => __('Edit'),
                        'icon' => 'bx bx-edit',
                        'url' => route('customers.edit', $customer->id),
                    ],
                    [
                        'label' => $customer->is_active ? __('Deactivate') : __('Activate'),
                        'icon' => $customer->is_active ? 'bx bx-x-circle' : 'bx bx-check-circle',
                        'onclick' => "toggleActive({$customer->id})",
                        'class' => $customer->is_active ? 'text-warning' : 'text-success',
                    ],
                    ['divider' => true],
                    [
                        'label' => __('Delete'),
                        'icon' => 'bx bx-trash',
                        'onclick' => "deleteCustomer({$customer->id})",
                        'class' => 'text-danger',
                    ],
                ];

                return view('components.datatable-actions', [
                    'id' => $customer->id,
                    'actions' => $actions,
                ])->render();
            })
            ->rawColumns(['customer_name', 'contact_info', 'customer_type_badge', 'company_name', 'credit_limit_formatted', 'status_column', 'actions'])
            ->make(true);
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        $customerGroups = CustomerGroup::active()->get();
        $customerTypes = CustomerType::cases();
        $companies = Company::where('is_active', true)->orderBy('name')->get();

        return view('crmcore::customers.create', compact('customerGroups', 'customerTypes', 'companies'));
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'company_name' => 'nullable|string|max:255',
            'customer_type' => 'required|string',
            'email' => 'nullable|email|max:255',
            'phone' => 'nullable|string|max:50',
            'mobile' => 'nullable|string|max:50',
            'website' => 'nullable|url|max:255',
            'tax_id' => 'nullable|string|max:100',
            'vat_number' => 'nullable|string|max:100',
            'credit_limit' => 'nullable|numeric|min:0',
            'customer_group_id' => 'nullable|exists:customer_groups,id',
            'company_id' => 'nullable|exists:companies,id',
            'payment_terms' => 'required|in:cod,net30,net60,prepaid',
            'discount_percentage' => 'nullable|numeric|min:0|max:100',
            'tax_exempt' => 'boolean',
            'notes' => 'nullable|string',
        ]);

        try {
            DB::beginTransaction();

            $data = $request->all();
            $data['status'] = CustomerStatus::Active->value;
            $data['is_active'] = true;
            $data['tax_exempt'] = $request->has('tax_exempt') ? 1 : 0;
            // customer_code will be auto-generated

            $customer = CoreCustomer::create($data);

            DB::commit();

            return Success::response([
                'message' => __('Customer created successfully'),
                'redirect' => route('customers.index'),
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Customer creation failed: '.$e->getMessage(), ['trace' => $e->getTraceAsString()]);

            return Error::response('Failed to create customer: '.$e->getMessage());
        }
    }

    /**
     * Display the specified resource.
     */
    public function show($id)
    {
        $customer = CoreCustomer::with(['customerGroup', 'company', 'contacts', 'addresses', 'documents', 'deals'])
            ->findOrFail($id);

        // Get customer statistics
        $stats = [
            'total_deals' => $customer->deals()->count(),
            'won_deals' => $customer->deals()->whereNotNull('won_at')->count(),
            'total_deal_value' => $customer->deals()->whereNotNull('won_at')->sum('value'),
        ];

        return view('crmcore::customers.show', compact('customer', 'stats'));
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit($id)
    {
        $customer = CoreCustomer::findOrFail($id);
        $customerGroups = CustomerGroup::active()->get();
        $customerTypes = CustomerType::cases();
        $customerStatuses = CustomerStatus::cases();
        $companies = Company::where('is_active', true)->orderBy('name')->get();

        return view('crmcore::customers.edit', compact('customer', 'customerGroups', 'customerTypes', 'customerStatuses', 'companies'));
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, $id)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'company_name' => 'nullable|string|max:255',
            'customer_type' => 'required|string',
            'status' => 'required|string',
            'email' => 'nullable|email|max:255',
            'phone' => 'nullable|string|max:50',
            'mobile' => 'nullable|string|max:50',
            'website' => 'nullable|url|max:255',
            'tax_id' => 'nullable|string|max:100',
            'vat_number' => 'nullable|string|max:100',
            'credit_limit' => 'nullable|numeric|min:0',
            'customer_group_id' => 'nullable|exists:customer_groups,id',
            'company_id' => 'nullable|exists:companies,id',
            'payment_terms' => 'required|in:cod,net30,net60,prepaid',
            'discount_percentage' => 'nullable|numeric|min:0|max:100',
            'tax_exempt' => 'boolean',
            'notes' => 'nullable|string',
            'is_active' => 'boolean',
        ]);

        try {
            DB::beginTransaction();

            $customer = CoreCustomer::findOrFail($id);

            $data = $request->all();
            $data['tax_exempt'] = $request->has('tax_exempt') ? 1 : 0;
            $data['is_active'] = $request->has('is_active') ? 1 : 0;

            $customer->update($data);

            DB::commit();

            return Success::response([
                'message' => __('Customer updated successfully'),
                'redirect' => route('customers.index'),
            ]);
        } catch (\Exception $e) {
            DB::rollBack();

            return Error::response(__('Failed to update customer'));
        }
    }

    /**
     * Toggle blacklist status
     */
    public function toggleBlacklist(Request $request, $id)
    {
        $request->validate([
            'blacklist' => 'required|boolean',
            'reason' => 'required_if:blacklist,true|nullable|string',
        ]);

        try {
            $customer = CoreCustomer::findOrFail($id);

            $customer->update([
                'is_blacklisted' => $request->blacklist,
                'blacklist_reason' => $request->blacklist ? $request->reason : null,
            ]);

            $message = $request->blacklist
                ? __('Customer has been blacklisted')
                : __('Customer has been removed from blacklist');

            return Success::response(['message' => $message]);
        } catch (\Exception $e) {
            return Error::response(__('Failed to update blacklist status'));
        }
    }

    /**
     * Get customer statistics
     */
    public function statistics()
    {
        try {
            $stats = [
                'total_customers' => CoreCustomer::count(),
                'active_customers' => CoreCustomer::where('is_active', true)
                    ->where('status', CustomerStatus::Active->value)
                    ->count(),
                'inactive_customers' => CoreCustomer::where('is_active', false)->count(),
                'new_customers_this_month' => CoreCustomer::whereMonth('created_at', now()->month)
                    ->whereYear('created_at', now()->year)
                    ->count(),
                'customers_with_company' => CoreCustomer::whereNotNull('company_name')
                    ->where('company_name', '!=', '')
                    ->count(),
                'b2b_customers' => CoreCustomer::where('customer_type', CustomerType::B2B->value)->count(),
                'b2c_customers' => CoreCustomer::where('customer_type', CustomerType::B2C->value)->count(),
            ];

            return Success::response($stats);
        } catch (\Exception $e) {
            Log::error('Customer statistics error: '.$e->getMessage());

            return Error::response(__('Failed to load statistics'));
        }
    }

    /**
     * Search customers for AJAX
     */
    public function search(Request $request)
    {
        $search = $request->get('q', '');

        $customers = CoreCustomer::where('is_active', true)
            ->where(function ($query) use ($search) {
                $query->where('name', 'like', "%{$search}%")
                    ->orWhere('customer_code', 'like', "%{$search}%")
                    ->orWhere('email', 'like', "%{$search}%")
                    ->orWhere('phone', 'like', "%{$search}%");
            })
            ->limit(20)
            ->get()
            ->map(function ($customer) {
                return [
                    'id' => $customer->id,
                    'text' => $customer->name.' ('.$customer->customer_code.')',
                    'name' => $customer->name,
                    'email' => $customer->email,
                    'phone' => $customer->phone,
                    'customer_code' => $customer->customer_code,
                ];
            });

        return response()->json(['results' => $customers]);
    }
}
