<?php

namespace App\Http\Controllers;

use App\Models\Notice;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Carbon\Carbon;

class NoticeController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        try {
            $user = auth()->user();
            
            $notices = Notice::with('creator')
                ->when($user->user_type == 'member', function($query) use ($user) {
                    return $query->where('status', 'published')
                        ->where(function($q) use ($user) {
                            $q->where('target_audience', 'all')
                              ->orWhere('target_audience', 'members')
                              ->orWhere(function($sub) use ($user) {
                                  $sub->where('target_audience', 'specific')
                                      ->whereJsonContains('specific_members', $user->id);
                              });
                        });
                })
                ->orderBy('pin_to_top', 'desc')
                ->orderBy('created_at', 'desc')
                ->paginate(20);
            
            return view('notices.index', compact('notices'));
            
        } catch (\Exception $e) {
            Log::error('Notice index error: ' . $e->getMessage());
            return view('notices.error', [
                'message' => 'নোটিশ লোড করতে সমস্যা হয়েছে।'
            ]);
        }
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        if (!in_array(auth()->user()->user_type, ['committee', 'admin'])) {
            abort(403, 'আপনি নোটিশ তৈরি করতে পারবেন না।');
        }
        
        $users = User::where('status', 'active')->get();
        return view('notices.create', compact('users'));
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        if (!in_array(auth()->user()->user_type, ['committee', 'admin'])) {
            abort(403, 'আপনি নোটিশ তৈরি করতে পারবেন না।');
        }
        
        $request->validate([
            'title' => 'required|string|max:200',
            'content' => 'required|string',
            'notice_type' => 'required|in:general,meeting,event,payment',
            'target_audience' => 'required|in:all,members,committee,specific',
            'publish_date' => 'nullable|date',
            'expiry_date' => 'nullable|date|after:publish_date',
            'status' => 'required|in:draft,published,expired',
            'attachment' => 'nullable|file|mimes:jpg,jpeg,png,pdf,doc,docx|max:5120',
            'is_important' => 'nullable|boolean',
            'send_notification' => 'nullable|boolean',
            'pin_to_top' => 'nullable|boolean',
            'priority' => 'nullable|in:low,medium,high,urgent',
            'specific_members' => 'required_if:target_audience,specific|array',
            'specific_members.*' => 'exists:users,id'
        ]);

        $specificMembers = null;
        if ($request->target_audience == 'specific' && $request->filled('specific_members')) {
            $specificMembers = json_encode($request->specific_members);
        }

        $notice = new Notice();
        $notice->title = $request->title;
        $notice->content = $request->content;
        $notice->notice_type = $request->notice_type;
        $notice->target_audience = $request->target_audience;
        $notice->specific_members = $specificMembers;
        $notice->publish_date = $request->publish_date;
        $notice->expiry_date = $request->expiry_date;
        $notice->status = $request->status;
        $notice->is_important = $request->boolean('is_important');
        $notice->send_notification = $request->boolean('send_notification');
        $notice->pin_to_top = $request->boolean('pin_to_top');
        $notice->priority = $request->priority ?? 'medium';
        $notice->created_by = Auth::id();

        if ($request->hasFile('attachment')) {
            $file = $request->file('attachment');
            $fileName = time() . '_' . $file->getClientOriginalName();
            $filePath = $file->storeAs('notices', $fileName, 'public');
            $notice->attachment = $filePath;
            $notice->attachment_name = $file->getClientOriginalName();
        }

        $notice->save();

        return redirect()->route('notices.index')
            ->with('success', 'নোটিশ সফলভাবে তৈরি করা হয়েছে।');
    }

    /**
     * Display the specified resource.
     */
    public function show($id)
    {
        try {
            $notice = Notice::with('creator')->findOrFail($id);
            $user = auth()->user();
            
            if ($notice->status != 'published') {
                if (!in_array($user->user_type, ['admin', 'committee'])) {
                    abort(403, 'আপনি এই নোটিশ দেখার অনুমতি রাখেন না।');
                }
            }
            
            if ($notice->target_audience == 'specific') {
                $specificMembers = json_decode($notice->specific_members ?? '[]', true);
                if (!in_array($user->id, $specificMembers) && !in_array($user->user_type, ['admin', 'committee'])) {
                    abort(403, 'এই নোটিশ শুধুমাত্র নির্দিষ্ট সদস্যদের জন্য।');
                }
            } elseif ($notice->target_audience == 'committee' && $user->user_type == 'member') {
                abort(403, 'এই নোটিশ শুধুমাত্র কমিটির সদস্যদের জন্য।');
            }
            
            $notice->increment('views');
            
            return view('notices.show', compact('notice'));
            
        } catch (\Exception $e) {
            Log::error('Notice show error: ' . $e->getMessage());
            abort(404, 'নোটিশ পাওয়া যায়নি');
        }
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit($id)
    {
        if (!in_array(auth()->user()->user_type, ['committee', 'admin'])) {
            abort(403, 'আপনি নোটিশ সম্পাদনা করতে পারবেন না।');
        }
        
        try {
            $notice = Notice::findOrFail($id);
            $users = User::where('status', 'active')->get();
            $specificMembers = json_decode($notice->specific_members ?? '[]', true);
            
            return view('notices.edit', compact('notice', 'users', 'specificMembers'));
            
        } catch (\Exception $e) {
            Log::error('Notice edit error: ' . $e->getMessage());
            abort(404, 'নোটিশ পাওয়া যায়নি');
        }
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, $id)
    {
        if (!in_array(auth()->user()->user_type, ['committee', 'admin'])) {
            abort(403, 'আপনি নোটিশ সম্পাদনা করতে পারবেন না।');
        }
        
        try {
            $notice = Notice::findOrFail($id);
            
            $request->validate([
                'title' => 'required|string|max:200',
                'content' => 'required|string',
                'notice_type' => 'required|in:general,meeting,event,payment',
                'target_audience' => 'required|in:all,members,committee,specific',
                'publish_date' => 'nullable|date',
                'expiry_date' => 'nullable|date|after:publish_date',
                'status' => 'required|in:draft,published,expired',
                'attachment' => 'nullable|file|mimes:jpg,jpeg,png,pdf,doc,docx|max:5120',
                'is_important' => 'nullable|boolean',
                'send_notification' => 'nullable|boolean',
                'pin_to_top' => 'nullable|boolean',
                'priority' => 'nullable|in:low,medium,high,urgent',
                'specific_members' => 'required_if:target_audience,specific|array',
                'specific_members.*' => 'exists:users,id'
            ]);

            $data = $request->only([
                'title', 'content', 'notice_type', 'target_audience',
                'publish_date', 'expiry_date', 'status', 'priority'
            ]);
            
            $data['is_important'] = $request->boolean('is_important');
            $data['send_notification'] = $request->boolean('send_notification');
            $data['pin_to_top'] = $request->boolean('pin_to_top');
            
            if ($request->target_audience == 'specific' && $request->filled('specific_members')) {
                $data['specific_members'] = json_encode($request->specific_members);
            } else {
                $data['specific_members'] = null;
            }

            if ($request->hasFile('attachment')) {
                if ($notice->attachment) {
                    Storage::disk('public')->delete($notice->attachment);
                }
                
                $file = $request->file('attachment');
                $fileName = time() . '_' . $file->getClientOriginalName();
                $filePath = $file->storeAs('notices', $fileName, 'public');
                $data['attachment'] = $filePath;
                $data['attachment_name'] = $file->getClientOriginalName();
            } elseif ($request->has('remove_attachment')) {
                if ($notice->attachment) {
                    Storage::disk('public')->delete($notice->attachment);
                }
                $data['attachment'] = null;
                $data['attachment_name'] = null;
            }

            $notice->update($data);

            return redirect()->route('notices.index')
                ->with('success', 'নোটিশ সফলভাবে আপডেট করা হয়েছে।');
                
        } catch (\Exception $e) {
            Log::error('Notice update error: ' . $e->getMessage());
            return back()->with('error', 'আপডেট করতে সমস্যা হয়েছে: ' . $e->getMessage());
        }
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy($id)
    {
        if (!in_array(auth()->user()->user_type, ['committee', 'admin'])) {
            abort(403, 'আপনি নোটিশ ডিলিট করতে পারবেন না।');
        }
        
        try {
            $notice = Notice::findOrFail($id);
            
            if ($notice->attachment) {
                Storage::disk('public')->delete($notice->attachment);
            }

            $notice->delete();

            return redirect()->route('notices.index')
                ->with('success', 'নোটিশ সফলভাবে ডিলিট করা হয়েছে।');
                
        } catch (\Exception $e) {
            Log::error('Notice destroy error: ' . $e->getMessage());
            return back()->with('error', 'ডিলিট করতে সমস্যা হয়েছে: ' . $e->getMessage());
        }
    }

    /**
     * গুরুত্বপূর্ণ নোটিশ
     */
    public function important()
    {
        try {
            $notices = Notice::where('is_important', true)
                ->where('status', 'published')
                ->with('creator')
                ->orderBy('created_at', 'desc')
                ->paginate(20);
                
            return view('notices.important', compact('notices'));
            
        } catch (\Exception $e) {
            Log::error('Important notices error: ' . $e->getMessage());
            return view('notices.error', ['message' => 'গুরুত্বপূর্ণ নোটিশ লোড করতে সমস্যা হয়েছে।']);
        }
    }

    /**
     * মিটিং নোটিশ
     */
    public function meetingNotices()
    {
        try {
            $notices = Notice::where('notice_type', 'meeting')
                ->where('status', 'published')
                ->with('creator')
                ->orderBy('created_at', 'desc')
                ->paginate(20);
                
            return view('notices.meeting', compact('notices'));
            
        } catch (\Exception $e) {
            Log::error('Meeting notices error: ' . $e->getMessage());
            return view('notices.error', ['message' => 'মিটিং নোটিশ লোড করতে সমস্যা হয়েছে।']);
        }
    }

    /**
     * খসড়া নোটিশের তালিকা
     */
    public function draftList()
    {
        if (!in_array(auth()->user()->user_type, ['admin', 'committee'])) {
            abort(403, 'আপনি এই পৃষ্ঠা দেখার অনুমতি রাখেন না।');
        }
        
        try {
            $notices = Notice::where('status', 'draft')
                ->with('creator')
                ->orderBy('created_at', 'desc')
                ->paginate(20);
            
            return view('notices.draft-list', compact('notices'));
            
        } catch (\Exception $e) {
            Log::error('Draft list error: ' . $e->getMessage());
            return view('notices.error', ['message' => 'খসড়া নোটিশ লোড করতে সমস্যা হয়েছে।']);
        }
    }

    /**
     * আসন্ন নোটিশ
     */
    public function upcoming()
    {
        try {
            $notices = Notice::where('status', 'published')
                ->where(function($query) {
                    $query->where('publish_date', '>', now())
                          ->orWhere(function($q) {
                              $q->whereNull('publish_date')
                                ->whereDate('created_at', '>=', now()->subDay());
                          });
                })
                ->with('creator')
                ->orderBy('publish_date', 'asc')
                ->paginate(20);
            
            return view('notices.upcoming', compact('notices'));
            
        } catch (\Exception $e) {
            Log::error('Upcoming notices error: ' . $e->getMessage());
            return view('notices.error', ['message' => 'আসন্ন নোটিশ লোড করতে সমস্যা হয়েছে।']);
        }
    }

    /**
     * প্রকাশ করা
     */
    public function publish($id)
    {
        if (!in_array(auth()->user()->user_type, ['committee', 'admin'])) {
            abort(403, 'আপনি নোটিশ প্রকাশ করতে পারবেন না।');
        }
        
        try {
            $notice = Notice::findOrFail($id);
            
            $notice->update([
                'status' => 'published',
                'publish_date' => $notice->publish_date ?? now()
            ]);
            
            return redirect()->route('notices.index')
                ->with('success', 'নোটিশ সফলভাবে প্রকাশ করা হয়েছে।');
                
        } catch (\Exception $e) {
            Log::error('Publish notice error: ' . $e->getMessage());
            return back()->with('error', 'প্রকাশ করতে সমস্যা হয়েছে: ' . $e->getMessage());
        }
    }

    /**
     * প্রিন্ট করার জন্য
     */
    public function printNotice($id)
    {
        try {
            $notice = Notice::with('creator')->findOrFail($id);
            return view('notices.print', compact('notice'));
            
        } catch (\Exception $e) {
            Log::error('Print notice error: ' . $e->getMessage());
            abort(404, 'নোটিশ পাওয়া যায়নি');
        }
    }

    /**
     * নোটিশের স্ট্যাটাস পরিবর্তন
     */
    public function changeStatus(Request $request, $id)
    {
        if (!in_array(auth()->user()->user_type, ['committee', 'admin'])) {
            abort(403, 'আপনি স্ট্যাটাস পরিবর্তন করতে পারবেন না।');
        }
        
        $request->validate([
            'status' => 'required|in:draft,published,expired'
        ]);

        try {
            $notice = Notice::findOrFail($id);
            
            $data = ['status' => $request->status];
            
            if ($request->status == 'published' && !$notice->publish_date) {
                $data['publish_date'] = now();
            }
            
            $notice->update($data);

            $statusMessages = [
                'draft' => 'খসড়া',
                'published' => 'প্রকাশিত',
                'expired' => 'মেয়াদোত্তীর্ণ'
            ];

            return redirect()->back()
                ->with('success', 'নোটিশ সফলভাবে ' . $statusMessages[$request->status] . ' হয়েছে।');
                
        } catch (\Exception $e) {
            Log::error('Change status error: ' . $e->getMessage());
            return back()->with('error', 'স্ট্যাটাস পরিবর্তন করতে সমস্যা হয়েছে: ' . $e->getMessage());
        }
    }

    /**
     * নির্দিষ্ট সদস্যের জন্য নোটিশ
     */
    public function forSpecificMembers()
    {
        $user = auth()->user();
        
        try {
            $notices = Notice::where('status', 'published')
                ->where('target_audience', 'specific')
                ->whereJsonContains('specific_members', $user->id)
                ->with('creator')
                ->orderBy('created_at', 'desc')
                ->paginate(20);
            
            return view('notices.specific-members', compact('notices'));
            
        } catch (\Exception $e) {
            Log::error('Specific members notices error: ' . $e->getMessage());
            return view('notices.error', ['message' => 'আপনার জন্য নোটিশ লোড করতে সমস্যা হয়েছে।']);
        }
    }

    /**
     * নোটিশ স্ট্যাটাস অনুযায়ী ফিল্টার
     */
    public function filterByStatus($status)
    {
        if (!in_array(auth()->user()->user_type, ['admin', 'committee'])) {
            abort(403);
        }
        
        $validStatuses = ['draft', 'published', 'expired'];
        
        if (!in_array($status, $validStatuses)) {
            abort(404);
        }

        try {
            $notices = Notice::where('status', $status)
                ->with('creator')
                ->orderBy('created_at', 'desc')
                ->paginate(20);
            
            $statusTitles = [
                'draft' => 'খসড়া নোটিশ',
                'published' => 'প্রকাশিত নোটিশ',
                'expired' => 'মেয়াদোত্তীর্ণ নোটিশ'
            ];

            return view('notices.status-index', [
                'notices' => $notices,
                'status' => $status,
                'statusTitle' => $statusTitles[$status]
            ]);
            
        } catch (\Exception $e) {
            Log::error('Filter by status error: ' . $e->getMessage());
            return view('notices.error', ['message' => 'নোটিশ ফিল্টার করতে সমস্যা হয়েছে।']);
        }
    }

    /**
     * সক্রিয় নোটিশের সংখ্যা
     */
    public function getActiveCount()
    {
        try {
            $count = Notice::where('status', 'published')
                ->where(function($query) {
                    $query->whereNull('expiry_date')
                          ->orWhere('expiry_date', '>=', now());
                })
                ->count();
            
            return response()->json(['count' => $count]);
            
        } catch (\Exception $e) {
            Log::error('Get active count error: ' . $e->getMessage());
            return response()->json(['count' => 0]);
        }
    }

    /**
     * নোটিশ সার্চ
     */
    public function search(Request $request)
    {
        $request->validate([
            'search' => 'nullable|string|max:255',
            'notice_type' => 'nullable|in:general,meeting,event,payment',
            'status' => 'nullable|in:draft,published,expired',
            'date_from' => 'nullable|date',
            'date_to' => 'nullable|date|after_or_equal:date_from',
            'priority' => 'nullable|in:low,medium,high,urgent',
            'is_important' => 'nullable|boolean',
        ]);

        $user = auth()->user();
        
        try {
            $notices = Notice::query();

            if (!in_array($user->user_type, ['admin', 'committee'])) {
                $notices->where('status', 'published');
            }

            if ($request->filled('search')) {
                $notices->where(function($query) use ($request) {
                    $query->where('title', 'like', '%' . $request->search . '%')
                          ->orWhere('content', 'like', '%' . $request->search . '%');
                });
            }

            if ($request->filled('notice_type')) {
                $notices->where('notice_type', $request->notice_type);
            }

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

            if ($request->filled('priority')) {
                $notices->where('priority', $request->priority);
            }

            if ($request->filled('is_important')) {
                $notices->where('is_important', $request->boolean('is_important'));
            }

            if ($request->filled('date_from')) {
                $notices->whereDate('created_at', '>=', $request->date_from);
            }

            if ($request->filled('date_to')) {
                $notices->whereDate('created_at', '<=', $request->date_to);
            }

            $notices = $notices->with('creator')
                ->orderBy('pin_to_top', 'desc')
                ->orderBy('created_at', 'desc')
                ->paginate(20);

            return view('notices.search', compact('notices'));
            
        } catch (\Exception $e) {
            Log::error('Search notices error: ' . $e->getMessage());
            return view('notices.error', ['message' => 'নোটিশ সার্চ করতে সমস্যা হয়েছে।']);
        }
    }

    /**
     * পিন করা নোটিশ
     */
    public function pinnedNotices()
    {
        try {
            $notices = Notice::where('pin_to_top', true)
                ->where('status', 'published')
                ->with('creator')
                ->orderBy('created_at', 'desc')
                ->paginate(20);
                
            return view('notices.pinned', compact('notices'));
            
        } catch (\Exception $e) {
            Log::error('Pinned notices error: ' . $e->getMessage());
            return view('notices.error', ['message' => 'পিন করা নোটিশ লোড করতে সমস্যা হয়েছে।']);
        }
    }

    /**
     * জরুরি নোটিশ
     */
    public function urgentNotices()
    {
        try {
            $notices = Notice::where('priority', 'urgent')
                ->where('status', 'published')
                ->with('creator')
                ->orderBy('created_at', 'desc')
                ->paginate(20);
                
            return view('notices.urgent', compact('notices'));
            
        } catch (\Exception $e) {
            Log::error('Urgent notices error: ' . $e->getMessage());
            return view('notices.error', ['message' => 'জরুরি নোটিশ লোড করতে সমস্যা হয়েছে।']);
        }
    }

    /**
     * মেয়াদ উত্তীর্ণ নোটিশ
     */
    public function expiredNotices()
    {
        if (!in_array(auth()->user()->user_type, ['admin', 'committee'])) {
            abort(403);
        }
        
        try {
            $notices = Notice::where('status', 'expired')
                ->orWhere(function($query) {
                    $query->where('status', 'published')
                        ->whereNotNull('expiry_date')
                        ->where('expiry_date', '<', now());
                })
                ->with('creator')
                ->orderBy('expiry_date', 'desc')
                ->paginate(20);
                
            return view('notices.expired', compact('notices'));
            
        } catch (\Exception $e) {
            Log::error('Expired notices error: ' . $e->getMessage());
            return view('notices.error', ['message' => 'মেয়াদোত্তীর্ণ নোটিশ লোড করতে সমস্যা হয়েছে।']);
        }
    }

    /**
     * টপিক অনুযায়ী নোটিশ
     */
    public function byNoticeType($type)
    {
        $validTypes = ['general', 'meeting', 'event', 'payment'];
        
        if (!in_array($type, $validTypes)) {
            abort(404);
        }

        $user = auth()->user();
        
        try {
            $notices = Notice::where('notice_type', $type)
                ->where('status', 'published')
                ->when($user->user_type == 'member', function($query) use ($user) {
                    return $query->where(function($q) use ($user) {
                        $q->where('target_audience', 'all')
                          ->orWhere('target_audience', 'members')
                          ->orWhere(function($sub) use ($user) {
                              $sub->where('target_audience', 'specific')
                                  ->whereJsonContains('specific_members', $user->id);
                          });
                    });
                })
                ->with('creator')
                ->orderBy('pin_to_top', 'desc')
                ->orderBy('created_at', 'desc')
                ->paginate(20);
            
            $typeTitles = [
                'general' => 'সাধারণ নোটিশ',
                'meeting' => 'মিটিং নোটিশ',
                'event' => 'ইভেন্ট নোটিশ',
                'payment' => 'পেমেন্ট নোটিশ'
            ];

            return view('notices.by-type', [
                'notices' => $notices,
                'type' => $type,
                'typeTitle' => $typeTitles[$type]
            ]);
            
        } catch (\Exception $e) {
            Log::error('By type notices error: ' . $e->getMessage());
            return view('notices.error', ['message' => 'নোটিশ টাইপ অনুযায়ী লোড করতে সমস্যা হয়েছে।']);
        }
    }

    /**
     * মাস অনুযায়ী নোটিশ
     */
    public function byMonth($year, $month)
    {
        try {
            $notices = Notice::whereYear('created_at', $year)
                ->whereMonth('created_at', $month)
                ->where('status', 'published')
                ->with('creator')
                ->orderBy('created_at', 'desc')
                ->paginate(20);
                
            return view('notices.by-month', compact('notices', 'year', 'month'));
            
        } catch (\Exception $e) {
            Log::error('By month notices error: ' . $e->getMessage());
            return view('notices.error', ['message' => 'মাস অনুযায়ী নোটিশ লোড করতে সমস্যা হয়েছে।']);
        }
    }

    /**
     * নোটিশ আর্কাইভ
     */
    public function archiveIndex()
    {
        if (!in_array(auth()->user()->user_type, ['admin', 'committee'])) {
            abort(403);
        }
        
        try {
            $notices = Notice::where('status', 'expired')
                ->orWhere(function($query) {
                    $query->where('status', 'published')
                        ->whereNotNull('expiry_date')
                        ->where('expiry_date', '<', now());
                })
                ->with('creator')
                ->orderBy('created_at', 'desc')
                ->paginate(20);
                
            return view('notices.archive-index', compact('notices'));
            
        } catch (\Exception $e) {
            Log::error('Archive index error: ' . $e->getMessage());
            return view('notices.error', ['message' => 'আর্কাইভ নোটিশ লোড করতে সমস্যা হয়েছে।']);
        }
    }

    /**
     * নোটিশ বুল্ক ডিলিট
     */
    public function bulkDelete(Request $request)
    {
        if (!in_array(auth()->user()->user_type, ['admin', 'committee'])) {
            abort(403);
        }
        
        $request->validate([
            'notice_ids' => 'required|array|min:1',
            'notice_ids.*' => 'exists:notices,id'
        ]);

        try {
            $notices = Notice::whereIn('id', $request->notice_ids)->get();
            
            foreach ($notices as $notice) {
                if ($notice->attachment) {
                    Storage::disk('public')->delete($notice->attachment);
                }
                $notice->delete();
            }

            return redirect()->route('notices.index')
                ->with('success', count($request->notice_ids) . 'টি নোটিশ সফলভাবে ডিলিট করা হয়েছে।');
                
        } catch (\Exception $e) {
            Log::error('Bulk delete error: ' . $e->getMessage());
            return back()->with('error', 'বাল্ক ডিলিট করতে সমস্যা হয়েছে: ' . $e->getMessage());
        }
    }
}