<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Offer;
use App\Models\Country;
use App\Models\Locale;
use App\Models\CountryStore;
use App\Models\Store;
use App\Models\Brand;
use App\Models\Category;
use App\Models\Occasion;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

class OfferController extends Controller
{
    /**
     * Display a listing of offers
     */
    public function index(Request $request)
    {
        $query = Offer::with([
            'translations.locale', 
            'countryStore.store.translations',
            'countryStore.country',
            'brand.translations',
            'categories.translations',
            'occasions.translations',
            'media'
        ]);

        // Get current country filter from session
        $currentCountry = current_filtered_country();
        $availableLocales = collect();
        $availableStores = collect();
        
        if ($currentCountry) {
            // Get locales for the selected country
            $availableLocales = Locale::where('country_id', $currentCountry->id)
                                    ->active()
                                    ->ordered()
                                    ->get();
            
            // Get stores for the selected country
            $availableStores = CountryStore::where('country_id', $currentCountry->id)
                                         ->with('store.translations')
                                         ->active()
                                         ->get();
            
            // Filter offers by country
            $query->whereHas('countryStore', function ($q) use ($currentCountry) {
                $q->where('country_id', $currentCountry->id);
            });
        }

        // Locale filter (for translations)
        if ($request->filled('locale_id')) {
            $query->whereHas('translations', function ($q) use ($request) {
                $q->where('locale_id', $request->locale_id);
            });
        }

        // Search functionality
        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->whereHas('translations', function ($tq) use ($search) {
                    $tq->where('title', 'like', "%{$search}%")
                        ->orWhere('description', 'like', "%{$search}%");
                })->orWhere('code', 'like', "%{$search}%");
            });
        }

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

        // Filter by type
        if ($request->filled('type')) {
            $query->where('type', $request->type);
        }

        // Filter by store
        if ($request->filled('store_id')) {
            $query->whereHas('countryStore', function ($q) use ($request) {
                $q->where('store_id', $request->store_id);
            });
        }

        // Filter by brand
        if ($request->filled('brand_id')) {
            $query->where('brand_id', $request->brand_id);
        }

        // Filter by category
        if ($request->filled('category_id')) {
            $query->whereHas('categories', function ($q) use ($request) {
                $q->where('categories.id', $request->category_id);
            });
        }

        // Filter by occasion
        if ($request->filled('occasion_id')) {
            $query->whereHas('occasions', function ($q) use ($request) {
                $q->where('occasions.id', $request->occasion_id);
            });
        }

        // Filter by featured
        if ($request->filled('featured')) {
            $query->where('is_featured', $request->featured === '1');
        }

        // Filter by exclusive
        if ($request->filled('exclusive')) {
            $query->where('is_exclusive', $request->exclusive === '1');
        }

        // Filter by expiry status
        if ($request->filled('expiry')) {
            if ($request->expiry === 'expired') {
                $query->whereNotNull('expires_at')
                      ->where('expires_at', '<=', now());
            } elseif ($request->expiry === 'active') {
                $query->where(function ($q) {
                    $q->whereNull('expires_at')
                      ->orWhere('expires_at', '>', now());
                });
            } elseif ($request->expiry === 'expiring_soon') {
                $query->whereNotNull('expires_at')
                      ->whereBetween('expires_at', [now(), now()->addDays(7)]);
            }
        }

        // Date range filter
        if ($request->filled('date_from')) {
            $query->whereDate('created_at', '>=', $request->date_from);
        }
        if ($request->filled('date_to')) {
            $query->whereDate('created_at', '<=', $request->date_to);
        }

        // Sort by popularity or created date
        $sortBy = $request->get('sort', 'created_at');
        $sortOrder = $request->get('order', 'desc');
        $query->orderBy($sortBy, $sortOrder);

        // Get paginated results
        $offers = $query->paginate(20)->withQueryString();

        // Get filter options
        $brands = Brand::active()->ordered()->get();
        $categories = Category::active()->ordered()->get();
        $occasions = Occasion::active()->ordered()->get();

        return view('admin.offers.index', compact(
            'offers',
            'availableLocales',
            'availableStores', 
            'currentCountry',
            'brands',
            'categories',
            'occasions'
        ));
    }

    /**
     * Show the form for creating a new offer
     */
    public function create()
    {
        $currentCountry = current_filtered_country();
        
        if (!$currentCountry) {
            flash_error(admin_trans('select_country_first'));
            return redirect()->route('admin.offers.index');
        }

        // Get available data for the form
        $availableLocales = Locale::where('country_id', $currentCountry->id)
                                  ->active()
                                  ->ordered()
                                  ->get();
        
        $availableStores = CountryStore::where('country_id', $currentCountry->id)
                                     ->with('store.translations')
                                     ->active()
                                     ->get();

        $brands = Brand::active()->ordered()->get();
        $categories = Category::active()->ordered()->get();
        $occasions = Occasion::active()->ordered()->get();

        return view('admin.offers.addedit', compact(
            'currentCountry',
            'availableLocales',
            'availableStores',
            'brands',
            'categories',
            'occasions'
        ));
    }

    /**
     * Store a newly created offer
     */
    public function store(Request $request)
    {
        $request->validate([
            'country_store_id' => 'required|exists:country_store,id',
            'brand_id' => 'nullable|exists:brands,id',
            'type' => 'required|in:code,deal',
            'code' => 'nullable|string|max:50',
            'promotion_type' => 'required|in:monetary,percent,upto_monetary,upto_percent,custom_label',
            'promotion_value' => 'nullable|numeric|min:0',
            'discount_value' => 'nullable|numeric|min:0|max:100',
            'regular_price' => 'nullable|numeric|min:0',
            'sale_price' => 'nullable|numeric|min:0',
            'currency' => 'nullable|string|size:3',
            'expires_at' => 'nullable|date|after:today',
            'translations' => 'required|array',
            'categories' => 'nullable|array',
            'categories.*' => 'exists:categories,id',
            'occasions' => 'nullable|array',
            'occasions.*' => 'exists:occasions,id',
            'is_featured' => 'nullable|boolean',
            'is_exclusive' => 'nullable|boolean',
            'is_free_shipping' => 'nullable|boolean',
            'is_new_customer' => 'nullable|boolean',
            'status' => 'required|in:draft,active',
            'images' => 'nullable|array',
            'images.*' => 'image|mimes:jpeg,png,jpg,webp|max:2048',
        ]);

        // Check if at least one translation exists
        $hasTranslation = false;
        foreach ($request->translations as $translation) {
            if (!empty($translation['title'])) {
                $hasTranslation = true;
                break;
            }
        }

        if (!$hasTranslation) {
            return back()->withErrors([
                'translations' => admin_trans('at_least_one_offer_title_required')
            ])->withInput();
        }

        DB::beginTransaction();
        try {
            // Create offer
            $offer = Offer::create([
                'user_id' => auth()->id(),
                'country_store_id' => $request->country_store_id,
                'brand_id' => $request->brand_id,
                'type' => $request->type,
                'code' => $request->code,
                'promotion_type' => $request->promotion_type,
                'promotion_value' => $request->promotion_value,
                'discount_value' => $request->discount_value,
                'regular_price' => $request->regular_price,
                'sale_price' => $request->sale_price,
                'currency' => $request->currency ?? 'USD',
                'expires_at' => $request->expires_at,
                'is_featured' => $request->boolean('is_featured'),
                'is_exclusive' => $request->boolean('is_exclusive'),
                'is_free_shipping' => $request->boolean('is_free_shipping'),
                'is_new_customer' => $request->boolean('is_new_customer'),
                'status' => $request->status,
            ]);

            // Store translations
            foreach ($request->translations as $localeId => $translation) {
                if (!empty($translation['title'])) {
                    $offer->translations()->create([
                        'locale_id' => $localeId,
                        'title' => $translation['title'],
                        'description' => $translation['description'] ?? null,
                        'final_url' => $translation['final_url'] ?? null,
                    ]);
                }
            }

            // Link categories
            if ($request->filled('categories')) {
                $offer->categories()->sync($request->categories);
            }

            // Link occasions
            if ($request->filled('occasions')) {
                $offer->occasions()->sync($request->occasions);
            }

            // Handle image uploads
            if ($request->hasFile('images')) {
                foreach ($request->file('images') as $image) {
                    $offer->addMedia($image)->toMediaCollection('images');
                }
            }

            DB::commit();
            flash_success(admin_trans('offer_created_successfully'));
            return redirect()->route('admin.offers.index');
        } catch (\Exception $e) {
            DB::rollBack();
            flash_error(admin_trans('error_creating_offer'));
            return back()->withInput();
        }
    }

    /**
     * Show the form for editing the specified offer
     */
    public function edit(Offer $offer)
    {
        $currentCountry = current_filtered_country();
        
        if (!$currentCountry) {
            flash_error(admin_trans('select_country_first'));
            return redirect()->route('admin.offers.index');
        }

        $offer->load([
            'translations.locale',
            'countryStore.store.translations',
            'countryStore.country',
            'brand.translations',
            'categories',
            'occasions',
            'media'
        ]);

        // Get available data for the form
        $availableLocales = Locale::where('country_id', $currentCountry->id)
                                  ->active()
                                  ->ordered()
                                  ->get();
        
        $availableStores = CountryStore::where('country_id', $currentCountry->id)
                                     ->with('store.translations')
                                     ->active()
                                     ->get();

        $brands = Brand::active()->ordered()->get();
        $categories = Category::active()->ordered()->get();
        $occasions = Occasion::active()->ordered()->get();

        return view('admin.offers.addedit', compact(
            'offer',
            'currentCountry',
            'availableLocales',
            'availableStores',
            'brands',
            'categories',
            'occasions'
        ));
    }

    /**
     * Update the specified offer
     */
    public function update(Request $request, Offer $offer)
    {
        $request->validate([
            'country_store_id' => 'required|exists:country_store,id',
            'brand_id' => 'nullable|exists:brands,id',
            'type' => 'required|in:code,deal',
            'code' => 'nullable|string|max:50',
            'promotion_type' => 'required|in:monetary,percent,upto_monetary,upto_percent,custom_label',
            'promotion_value' => 'nullable|numeric|min:0',
            'discount_value' => 'nullable|numeric|min:0|max:100',
            'regular_price' => 'nullable|numeric|min:0',
            'sale_price' => 'nullable|numeric|min:0',
            'currency' => 'nullable|string|size:3',
            'expires_at' => 'nullable|date',
            'translations' => 'required|array',
            'categories' => 'nullable|array',
            'categories.*' => 'exists:categories,id',
            'occasions' => 'nullable|array',
            'occasions.*' => 'exists:occasions,id',
            'is_featured' => 'nullable|boolean',
            'is_exclusive' => 'nullable|boolean',
            'is_free_shipping' => 'nullable|boolean',
            'is_new_customer' => 'nullable|boolean',
            'status' => 'required|in:draft,active',
            'images' => 'nullable|array',
            'images.*' => 'image|mimes:jpeg,png,jpg,webp|max:2048',
        ]);

        // Check if at least one translation exists
        $hasTranslation = false;
        foreach ($request->translations as $translation) {
            if (!empty($translation['title'])) {
                $hasTranslation = true;
                break;
            }
        }

        if (!$hasTranslation) {
            return back()->withErrors([
                'translations' => admin_trans('at_least_one_offer_title_required')
            ])->withInput();
        }

        DB::beginTransaction();
        try {
            // Update offer
            $offer->update([
                'country_store_id' => $request->country_store_id,
                'brand_id' => $request->brand_id,
                'type' => $request->type,
                'code' => $request->code,
                'promotion_type' => $request->promotion_type,
                'promotion_value' => $request->promotion_value,
                'discount_value' => $request->discount_value,
                'regular_price' => $request->regular_price,
                'sale_price' => $request->sale_price,
                'currency' => $request->currency ?? 'USD',
                'expires_at' => $request->expires_at,
                'is_featured' => $request->boolean('is_featured'),
                'is_exclusive' => $request->boolean('is_exclusive'),
                'is_free_shipping' => $request->boolean('is_free_shipping'),
                'is_new_customer' => $request->boolean('is_new_customer'),
                'status' => $request->status,
            ]);

            // Clear and update translations
            $offer->translations()->delete();
            foreach ($request->translations as $localeId => $translation) {
                if (!empty($translation['title'])) {
                    $offer->translations()->create([
                        'locale_id' => $localeId,
                        'title' => $translation['title'],
                        'description' => $translation['description'] ?? null,
                        'final_url' => $translation['final_url'] ?? null,
                    ]);
                }
            }

            // Update categories
            if ($request->filled('categories')) {
                $offer->categories()->sync($request->categories);
            } else {
                $offer->categories()->detach();
            }

            // Update occasions
            if ($request->filled('occasions')) {
                $offer->occasions()->sync($request->occasions);
            } else {
                $offer->occasions()->detach();
            }

            // Handle new image uploads
            if ($request->hasFile('images')) {
                foreach ($request->file('images') as $image) {
                    $offer->addMedia($image)->toMediaCollection('images');
                }
            }

            DB::commit();
            flash_success(admin_trans('offer_updated_successfully'));
            return redirect()->route('admin.offers.index');
        } catch (\Exception $e) {
            DB::rollBack();
            flash_error(admin_trans('error_updating_offer'));
            return back()->withInput();
        }
    }

    /**
     * Remove the specified offer
     */
    public function destroy(Offer $offer)
    {
        try {
            $offer->delete();
            flash_success(admin_trans('offer_deleted_successfully'));
        } catch (\Exception $e) {
            flash_error(admin_trans('error_deleting_offer'));
        }

        return redirect()->route('admin.offers.index');
    }

    /**
     * Toggle offer status
     */
    public function toggleStatus(Offer $offer)
    {
        try {
            $newStatus = $offer->status === 'active' ? 'draft' : 'active';
            $offer->update(['status' => $newStatus]);
            
            flash_success(admin_trans('offer_status_updated'));
        } catch (\Exception $e) {
            flash_error(admin_trans('error_updating_status'));
        }

        return back();
    }

    /**
     * Toggle offer featured status
     */
    public function toggleFeatured(Offer $offer)
    {
        try {
            $offer->update(['is_featured' => !$offer->is_featured]);

            $message = $offer->is_featured
                ? admin_trans('offer_featured_successfully')
                : admin_trans('offer_unfeatured_successfully');

            flash_success($message);
        } catch (\Exception $e) {
            flash_error(admin_trans('error_updating_featured'));
        }

        return back();
    }

    /**
     * Bulk actions
     */
    public function bulkAction(Request $request)
    {
        $request->validate([
            'action' => 'required|in:delete,activate,deactivate,feature,unfeature,expire',
            'selected' => 'required|array',
            'selected.*' => 'exists:offers,id',
        ]);

        $offers = Offer::whereIn('id', $request->selected);
        $count = count($request->selected);

        try {
            switch ($request->action) {
                case 'delete':
                    $offers->delete();
                    break;

                case 'activate':
                    $offers->update(['status' => 'active']);
                    break;

                case 'deactivate':
                    $offers->update(['status' => 'draft']);
                    break;

                case 'feature':
                    $offers->update(['is_featured' => true]);
                    break;

                case 'unfeature':
                    $offers->update(['is_featured' => false]);
                    break;

                case 'expire':
                    $offers->update(['expires_at' => now()]);
                    break;
            }

            return response()->json([
                'success' => true,
                'message' => "$count " . admin_trans('offers') . " {$request->action}d " . admin_trans('successfully')
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => admin_trans('error_bulk_action')
            ]);
        }
    }

    /**
     * Remove media from offer
     */
    public function removeMedia(Offer $offer, $collection, $mediaId)
    {
        try {
            $media = $offer->getMedia($collection)->where('id', $mediaId)->first();
            
            if ($media) {
                $media->delete();
            }

            return response()->json([
                'success' => true,
                'message' => admin_trans('media_removed_successfully')
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => admin_trans('error_removing_media')
            ], 500);
        }
    }

    /**
     * Get offer statistics
     */
    public function getStats(Offer $offer)
    {
        try {
            $stats = [
                'favorites_count' => $offer->favorites_count,
                'uses_count' => $offer->uses_count,
                'views_count' => $offer->views_count,
                'impressions_count' => $offer->impressions_count,
                'popularity' => $offer->popularity,
                'last_usage' => $offer->last_usage,
                'created_at' => $offer->created_at,
                'expires_at' => $offer->expires_at,
                'is_expired' => $offer->is_expired,
                'saving_amount' => $offer->saving_amount,
                'saving_percentage' => $offer->saving_percentage,
            ];

            return response()->json([
                'success' => true,
                'stats' => $stats
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => admin_trans('error_loading_stats')
            ], 500);
        }
    }
}