<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Client;
use App\Models\ClientDiscount;
use App\Models\Currency;
use App\Models\Product;
use App\Models\ProductGroup;
use App\Services\ClientDiscountService;
use App\Services\DiscountManager;
use App\Traits\LogsAdminActivity;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;

class ClientDiscountController extends Controller
{
    use LogsAdminActivity;
    protected $clientDiscountService;

    protected $discountManager;

    public function __construct(
        ClientDiscountService $clientDiscountService,
        DiscountManager $discountManager
    ) {
        $this->clientDiscountService = $clientDiscountService;
        $this->discountManager = $discountManager;
    }

    /**
     * Display a listing of client discounts
     */
    public function index()
    {
        return view('admin.client-discounts.index');
    }

    /**
     * Show the form for creating a new client discount
     */
    public function create()
    {
        $clients = Client::where('is_deleted', 0)
            ->orderBy('first_name')
            ->orderBy('last_name')
            ->get();

        $currencies = Currency::where('status', true)->get();
        $products = Product::where('status', 'active')->get();
        $productGroups = ProductGroup::all();

        return view('admin.client-discounts.create', compact(
            'clients',
            'currencies',
            'products',
            'productGroups'
        ));
    }

    /**
     * Store a newly created client discount
     */
    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'client_id' => ['required', 'exists:clients,id'],
            'name' => ['required', 'string', 'max:255'],
            'description' => ['nullable', 'string'],
            'type' => ['required', 'in:percentage,fixed_amount'],
            'discount_value' => ['required', 'numeric', 'min:0'],
            'currency_id' => ['required_if:type,fixed_amount', 'nullable', 'exists:currencies,id'],
            'min_order_amount' => ['nullable', 'numeric', 'min:0'],
            'max_discount_amount' => ['nullable', 'numeric', 'min:0'],
            'applies_to' => ['required', 'in:all_products,specific_products,product_groups'],
            'product_ids' => ['required_if:applies_to,specific_products', 'nullable', 'array'],
            'product_group_ids' => ['required_if:applies_to,product_groups', 'nullable', 'array'],
            'is_active' => ['boolean'],
            'starts_at' => ['nullable', 'date'],
            'expires_at' => ['nullable', 'date', 'after:starts_at'],
        ]);

        // Custom validation
        $errors = $this->discountManager->validateDiscountRules($request->all(), 'client_specific');
        if (! empty($errors)) {
            return back()->withErrors($errors)->withInput();
        }

        if ($validator->fails()) {
            return back()->withErrors($validator)->withInput();
        }

        $data = $validator->validated();
        $data['created_by_admin_id'] = Auth::guard('admin')->id();

        try {
            $discount = $this->clientDiscountService->createClientDiscount($data);

            $this->logCreated($discount, "Created client discount #{$discount->id} - {$discount->name}", $discount->client_id);

            return redirect()
                ->route('admin.client-discounts.show', $discount)
                ->with('success', __('admin/clients.messages_discount_created'));

        } catch (\Exception $e) {
            return back()
                ->withErrors(['error' => __('admin/clients.messages_discount_create_error', ['error' => $e->getMessage()])])
                ->withInput();
        }
    }

    /**
     * Display the specified client discount
     */
    public function show(ClientDiscount $clientDiscount)
    {
        $clientDiscount->load(['client', 'currency', 'createdByAdmin']);

        $stats = $this->clientDiscountService->getClientDiscountStats($clientDiscount->client);

        return view('admin.client-discounts.show', compact('clientDiscount', 'stats'));
    }

    /**
     * Show the form for editing the specified client discount
     */
    public function edit(ClientDiscount $clientDiscount)
    {
        $clients = Client::where('is_deleted', 0)
            ->orderBy('first_name')
            ->orderBy('last_name')
            ->get();

        $currencies = Currency::where('status', true)->get();
        $products = Product::where('status', 'active')->get();
        $productGroups = ProductGroup::all();

        return view('admin.client-discounts.edit', compact(
            'clientDiscount',
            'clients',
            'currencies',
            'products',
            'productGroups'
        ));
    }

    /**
     * Update the specified client discount
     */
    public function update(Request $request, ClientDiscount $clientDiscount)
    {
        $validator = Validator::make($request->all(), [
            'client_id' => ['required', 'exists:clients,id'],
            'name' => ['required', 'string', 'max:255'],
            'description' => ['nullable', 'string'],
            'type' => ['required', 'in:percentage,fixed_amount'],
            'discount_value' => ['required', 'numeric', 'min:0'],
            'currency_id' => ['required_if:type,fixed_amount', 'nullable', 'exists:currencies,id'],
            'min_order_amount' => ['nullable', 'numeric', 'min:0'],
            'max_discount_amount' => ['nullable', 'numeric', 'min:0'],
            'applies_to' => ['required', 'in:all_products,specific_products,product_groups'],
            'product_ids' => ['required_if:applies_to,specific_products', 'nullable', 'array'],
            'product_group_ids' => ['required_if:applies_to,product_groups', 'nullable', 'array'],
            'is_active' => ['boolean'],
            'starts_at' => ['nullable', 'date'],
            'expires_at' => ['nullable', 'date', 'after:starts_at'],
        ]);

        // Custom validation
        $errors = $this->discountManager->validateDiscountRules($request->all(), 'client_specific');
        if (! empty($errors)) {
            return back()->withErrors($errors)->withInput();
        }

        if ($validator->fails()) {
            return back()->withErrors($validator)->withInput();
        }

        try {
            $data = $validator->validated();
            if (! array_key_exists('is_active', $data)) {
                $data['is_active'] = false;
            }
            $this->clientDiscountService->updateClientDiscount($clientDiscount, $data);

            $this->logUpdated($clientDiscount, "Updated client discount #{$clientDiscount->id} - {$clientDiscount->name}", $clientDiscount->client_id);

            return redirect()
                ->route('admin.client-discounts.show', $clientDiscount)
                ->with('success', __('admin/clients.messages_discount_updated'));

        } catch (\Exception $e) {
            return back()
                ->withErrors(['error' => __('admin/clients.messages_discount_update_error', ['error' => $e->getMessage()])])
                ->withInput();
        }
    }

    /**
     * Remove the specified client discount
     */
    public function destroy(ClientDiscount $clientDiscount)
    {
        try {
            $this->logDeleted($clientDiscount, "Deleted client discount #{$clientDiscount->id} - {$clientDiscount->name}", $clientDiscount->client_id);

            $this->clientDiscountService->deleteClientDiscount($clientDiscount);

            return response()->json([
                'success' => true,
                'message' => __('admin/common.messages_client_discount_deleted'),
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => __('admin/common.messages_discount_delete_error'),
            ], 500);
        }
    }

    /**
     * Toggle client discount status
     */
    public function toggleStatus(ClientDiscount $clientDiscount)
    {
        try {
            $this->clientDiscountService->toggleDiscountStatus($clientDiscount);

            $this->logUpdated($clientDiscount, "Toggled client discount #{$clientDiscount->id} status", $clientDiscount->client_id);

            return response()->json([
                'success' => true,
                'message' => __('admin/clients.messages_discount_status_updated'),
                'is_active' => $clientDiscount->fresh()->is_active,
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => __('admin/clients.messages_discount_status_error'),
            ], 500);
        }
    }

    /**
     * Get client discounts records for DataTable
     */
    public function records(Request $request)
    {
        $query = ClientDiscount::with(['client', 'currency', 'createdByAdmin'])
            ->orderBy('created_at', 'desc');

        // Search filters
        if ($request->has('search') && ! empty($request->search['value'])) {
            $search = $request->search['value'];
            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                    ->orWhereHas('client', function ($clientQuery) use ($search) {
                        $clientQuery->where('first_name', 'like', "%{$search}%")
                            ->orWhere('last_name', 'like', "%{$search}%")
                            ->orWhere('email', 'like', "%{$search}%");
                    });
            });
        }

        $totalRecords = $query->count();

        if ($request->has('start')) {
            $query->skip($request->start);
        }

        if ($request->has('length')) {
            $query->take($request->length);
        }

        $discounts = $query->get();

        return response()->json([
            'draw' => intval($request->draw),
            'recordsTotal' => $totalRecords,
            'recordsFiltered' => $totalRecords,
            'data' => $discounts->map(function ($discount) {
                return [
                    'id' => $discount->id,
                    'name' => $discount->name,
                    'client' => $discount->client ? $discount->client->first_name.' '.$discount->client->last_name : 'N/A',
                    'type' => $discount->type === 'percentage' ? '%'.$discount->discount_value :
                             ($discount->currency ? $discount->currency->prefix : '').$discount->discount_value,
                    'applies_to' => ucfirst(str_replace('_', ' ', $discount->applies_to)),
                    'is_active' => $discount->is_active,
                    'expires_at' => $discount->expires_at ? $discount->expires_at->format('d.m.Y') : '-',
                    'created_at' => $discount->created_at->format('d.m.Y H:i'),
                    'actions' => [
                        'show' => route('admin.client-discounts.show', $discount),
                        'edit' => route('admin.client-discounts.edit', $discount),
                        'delete' => route('admin.client-discounts.destroy', $discount),
                        'toggle' => route('admin.client-discounts.toggle-status', $discount),
                    ],
                ];
            }),
        ]);
    }
}
