<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
use PDF;

class NoticeController extends Controller
{
    // GET /api/notices
    public function index(Request $request)
    {
        $user = Auth::user();
        if (!$user || !$user->society_id) {
            return response()->json(['status' => 'error', 'message' => 'Unauthorized'], 403);
        }

        $query = DB::table('notices')->where('society_id', $user->society_id);

        // Filters
        if ($request->has('type')) {
            $query->where('type', $request->type);
        }

        if ($request->has('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('title', 'like', "%{$search}%")
                    ->orWhere('content', 'like', "%{$search}%");
            });
        }

        // Role based visibility
        // Members typically see only 'published' notices.
        // Admins can see all.
        // For simplicity, let's allow viewing all but frontend filters 'draft' for members?
        // Better:
        $isAdmin = in_array($user->role, ['society_admin', 'secretary', 'super_admin']);
        if (!$isAdmin) {
            $query->where('status', 'published');
            // Check expiration
            $query->where(function ($q) {
                $q->whereNull('expires_at')->orWhereDate('expires_at', '>=', now());
            });
        }

        $notices = $query->orderBy('created_at', 'desc')->paginate(10);

        return response()->json($notices);
    }

    // POST /api/notices
    public function store(Request $request)
    {
        $user = Auth::user();
        if (!$user->society_id) {
            return response()->json(['status' => 'error', 'message' => 'User not associated with a society'], 400);
        }

        $isAdmin = in_array($user->role, ['society_admin', 'secretary', 'super_admin']);

        if (!$isAdmin) {
            return response()->json(['status' => 'error', 'message' => 'Unauthorized'], 403);
        }

        $validator = Validator::make($request->all(), [
            'title' => 'required|string|max:255',
            'content' => 'required|string',
            'type' => 'required|in:circular,meeting,event,general,minutes',
            'status' => 'required|in:draft,published,archived',
            'attachment' => 'nullable|file|mimes:pdf,doc,docx,jpg,png|max:5120',
            'expires_at' => 'nullable|date|after_or_equal:today'
        ]);

        if ($validator->fails()) {
            return response()->json(['status' => 'error', 'message' => 'Validation failed', 'errors' => $validator->errors()], 422);
        }

        /* 
        // Manual file upload handling - Replaced by PDF Generation
        $attachmentPath = null;
        if ($request->hasFile('attachment')) {
            $attachmentPath = $request->file('attachment')->store('notices', 'public');
        }
        */

        // Initial Insert
        $id = DB::table('notices')->insertGetId([
            'society_id' => $user->society_id,
            'created_by' => $user->id,
            'title' => $request->title,
            'content' => $request->content,
            'type' => $request->type,
            'status' => $request->status,
            // attachment will be updated after PDF generation
            'attachment' => null,
            'published_at' => $request->status === 'published' ? now() : null,
            'expires_at' => $request->expires_at,
            'created_at' => now(),
            'updated_at' => now()
        ]);

        // Fetch Society Name & User Name for PDF
        $society = DB::table('societies')->where('id', $user->society_id)->first();
        $societyName = $society ? $society->name : 'Society Notice'; // Fallback

        $notice = DB::table('notices')->where('id', $id)->first();

        // Generate PDF
        $pdf = PDF::loadView('notices.pdf', [
            'notice' => $notice,
            'society_name' => $societyName,
            'creator_name' => $user->name ?? 'Administrator'
        ]);

        $fileName = 'notice_' . $id . '.pdf';
        Storage::disk('public')->put('notices/' . $fileName, $pdf->output());

        // Update record
        DB::table('notices')->where('id', $id)->update(['attachment' => 'notices/' . $fileName]);

        return response()->json(['status' => 'success', 'message' => 'Notice created successfully', 'id' => $id], 201);
    }

    // GET /api/notices/{id}
    public function show($id)
    {
        $user = Auth::user();
        $notice = DB::table('notices')->where('id', $id)->where('society_id', $user->society_id)->first();

        if (!$notice) {
            return response()->json(['status' => 'error', 'message' => 'Notice not found'], 404);
        }

        return response()->json($notice);
    }

    // PUT /api/notices/{id}
    public function update(Request $request, $id)
    {
        $user = Auth::user();
        $isAdmin = in_array($user->role, ['society_admin', 'secretary', 'super_admin']);

        if (!$isAdmin) {
            return response()->json(['status' => 'error', 'message' => 'Unauthorized'], 403);
        }

        $notice = DB::table('notices')->where('id', $id)->where('society_id', $user->society_id)->first();
        if (!$notice) {
            return response()->json(['status' => 'error', 'message' => 'Notice not found'], 404);
        }

        $validator = Validator::make($request->all(), [
            'title' => 'sometimes|required|string|max:255',
            'content' => 'sometimes|required|string',
            'type' => 'sometimes|required|in:circular,meeting,event,general,minutes',
            'status' => 'sometimes|required|in:draft,published,archived',
            'attachment' => 'nullable|file|mimes:pdf,doc,docx,jpg,png|max:5120',
            'expires_at' => 'nullable|date|after_or_equal:today'
        ]);

        if ($validator->fails()) {
            return response()->json(['status' => 'error', 'errors' => $validator->errors()], 422);
        }

        $updates = $request->only(['title', 'content', 'type', 'status', 'expires_at']);

        if ($request->hasFile('attachment')) {
            // Delete old
            if ($notice->attachment) {
                Storage::disk('public')->delete($notice->attachment);
            }
            $updates['attachment'] = $request->file('attachment')->store('notices', 'public');
        }

        if ($request->status === 'published' && $notice->status !== 'published') {
            $updates['published_at'] = now();
        }

        $updates['updated_at'] = now();

        DB::table('notices')->where('id', $id)->update($updates);

        // Regenerate PDF on update
        $updatedNotice = DB::table('notices')->where('id', $id)->first();
        $society = DB::table('societies')->where('id', $user->society_id)->first();
        $societyName = $society ? $society->name : 'Society Notice';

        $pdf = PDF::loadView('notices.pdf', [
            'notice' => $updatedNotice,
            'society_name' => $societyName,
            'creator_name' => $user->name ?? 'Administrator'
        ]);

        $fileName = 'notice_' . $id . '.pdf';
        Storage::disk('public')->put('notices/' . $fileName, $pdf->output());

        // Ensure attachment path is set (if it was null/lost)
        DB::table('notices')->where('id', $id)->update(['attachment' => 'notices/' . $fileName]);

        return response()->json(['status' => 'success', 'message' => 'Notice updated successfully']);
    }

    // DELETE /api/notices/{id}
    public function destroy($id)
    {
        $user = Auth::user();
        $isAdmin = in_array($user->role, ['society_admin', 'secretary', 'super_admin']);

        if (!$isAdmin) {
            return response()->json(['status' => 'error', 'message' => 'Unauthorized'], 403);
        }

        $notice = DB::table('notices')->where('id', $id)->where('society_id', $user->society_id)->first();
        if (!$notice) {
            return response()->json(['status' => 'error', 'message' => 'Notice not found'], 404);
        }

        DB::table('notices')->where('id', $id)->delete();

        // Optionally delete file
        if ($notice->attachment) {
            Storage::disk('public')->delete($notice->attachment);
        }

        return response()->json(['status' => 'success', 'message' => 'Notice deleted']);
    }

    // GET /api/notices/{id}/download
    public function downloadAttachment($id)
    {
        $user = Auth::user();
        $notice = DB::table('notices')->where('id', $id)->where('society_id', $user->society_id)->first();

        if (!$notice || !$notice->attachment) {
            return response()->json(['status' => 'error', 'message' => 'File not found'], 404);
        }

        $filePath = storage_path('app/public/' . $notice->attachment);

        if (!file_exists($filePath)) {
            return response()->json(['status' => 'error', 'message' => 'File missing from server'], 404);
        }

        $headers = [
            'Content-Type' => mime_content_type($filePath),
            'Content-Disposition' => 'inline; filename="' . basename($filePath) . '"',
        ];

        return response(file_get_contents($filePath), 200, $headers);
    }
}
