<?php

namespace App\Http\Controllers;

use App\Models\Subject;
use App\Models\SubjectPaper;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class SubjectController extends Controller
{
    /**
     * Display a listing of subjects
     */
    public function index(Request $request)
    {
        $query = Subject::query();

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

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

        $subjects = $query->latest()->paginate(15);

        return view('subjects.index', compact('subjects'));
    }

    /**
     * Show the form for creating a new subject
     */
    public function create()
    {
        return view('subjects.create');
    }

    /**
     * Store a newly created subject (Transactional)
     */
    public function store(Request $request)
    {
        // 1. Validate Subject Identity
        $request->validate([
            'name' => 'required|string|max:255|unique:subjects,name',
            'paper_type' => 'required|in:single,double',
            // Paper 1
            'paper_1_code' => 'required|string|max:10|unique:subject_papers,paper_code',
            // Paper 2 (if double)
            'paper_2_code' => 'exclude_unless:paper_type,double|required|string|max:10|unique:subject_papers,paper_code',
        ]);

        try {
            DB::transaction(function () use ($request) {
                // Determine Identity Code (Paper 1 code usually acts as main ref)
                $mainCode = $request->paper_1_code;
                
                // Determine Overall Practical Status
                $hasPractical = $request->paper_type === 'double' 
                    ? ($request->has('p1_has_practical') || $request->has('p2_has_practical'))
                    : $request->has('p1_has_practical');

                // Create Master
                $subject = Subject::create([
                    'name' => $request->name,
                    'code' => $mainCode, 
                    'short_name' => $request->short_name,
                    'has_multiple_papers' => $request->paper_type === 'double',
                    'is_4th_subject_eligible' => $request->has('is_4th_subject_eligible'),
                    'has_practical' => $hasPractical ? 1 : 0
                ]);

                // Create Paper 1
                SubjectPaper::create([
                    'subject_id' => $subject->id,
                    'paper_type' => $request->paper_type === 'double' ? 'first' : 'single',
                    'paper_code' => $request->paper_1_code,
                    'name_suffix' => $request->paper_type === 'double' ? '1st Paper' : null,
                    'has_cq' => $request->has('p1_has_cq') ? 1 : 0,
                    'has_mcq' => $request->has('p1_has_mcq') ? 1 : 0,
                    'has_practical' => $request->has('p1_has_practical') ? 1 : 0,
                    'full_marks' => 100 
                ]);

                // Create Paper 2
                if ($request->paper_type === 'double') {
                    SubjectPaper::create([
                        'subject_id' => $subject->id,
                        'paper_type' => 'second',
                        'paper_code' => $request->paper_2_code,
                        'name_suffix' => '2nd Paper',
                        'has_cq' => $request->has('p2_has_cq') ? 1 : 0,
                        'has_mcq' => $request->has('p2_has_mcq') ? 1 : 0,
                        'has_practical' => $request->has('p2_has_practical') ? 1 : 0,
                        'full_marks' => 100
                    ]);
                }
            });

            return redirect()->route('subjects.index')
                ->with('success', 'Subject & Papers created successfully.');

        } catch (\Exception $e) {
            return back()->withInput()->with('error', 'Creation failed: ' . $e->getMessage());
        }
    }

    public function checkCode(Request $request)
    {
        $code = $request->query('code');
        $exists = SubjectPaper::where('paper_code', $code)->exists();
        return response()->json(['exists' => $exists]);
    }

    /**
     * Display the specified subject
     */
    public function show(Subject $subject)
    {
        return view('subjects.show', compact('subject'));
    }

    /**
     * Show the form for editing the specified subject
     */
    public function edit(Subject $subject)
    {
        return view('subjects.edit', compact('subject'));
    }

    /**
     * Update the specified subject
     */
    public function update(Request $request, Subject $subject)
    {
        $request->validate([
            'name' => 'required|string|max:255|unique:subjects,name,' . $subject->id,
            // 'status' => 'required|in:active,inactive', // Removed as column doesn't exist
            'papers' => 'required|array',
            'papers.*.code' => 'required|string|distinct|max:10', // Basic check, complex unique check below
        ]);

        // Custom Unique Validation for Paper Codes
        foreach ($request->papers as $id => $data) {
            $exists = SubjectPaper::where('paper_code', $data['code'])
                ->where('id', '!=', $id)
                ->exists();
            if ($exists) {
                return back()->withInput()->withErrors(['papers.'.$id.'.code' => "Code {$data['code']} is already taken."]);
            }
        }

        try {
            DB::transaction(function () use ($request, $subject) {
                // 1. Update Master
                $subject->update([
                    'name' => $request->name,
                    'short_name' => $request->short_name,
                    'is_4th_subject_eligible' => $request->is_4th_subject_eligible,
                ]);

                // 2. Update Papers
                $hasPractical = false;
                foreach ($request->papers as $id => $data) {
                    $paper = SubjectPaper::findOrFail($id);
                    if ($paper->subject_id !== $subject->id) continue; // Security check

                    $hasP = isset($data['has_practical']) ? 1 : 0;
                    if($hasP) $hasPractical = true;

                    $paper->update([
                        'paper_code' => $data['code'],
                        'has_cq' => isset($data['has_cq']) ? 1 : 0,
                        'has_mcq' => isset($data['has_mcq']) ? 1 : 0,
                        'has_practical' => $hasP,
                    ]);

                    // Sync Main Code if this is the first/single paper
                    if ($paper->paper_type !== 'second') {
                        $subject->update(['code' => $data['code']]);
                    }
                }
                
                // 3. Sync Overall Practical Status to Master
                $subject->update(['has_practical' => $hasPractical ? 1 : 0]);
            });

            return redirect()->route('subjects.show', $subject->id)->with('success', 'Subject updated successfully.');

        } catch (\Exception $e) {
            return back()->withInput()->with('error', 'Update failed: ' . $e->getMessage());
        }
    }

    /**
     * Remove the specified subject
     */
    public function destroy(Subject $subject)
    {
        $subject->delete();
        return redirect()->route('subjects.index')->with('success', 'Subject deleted successfully!');
    }

    /**
     * Get subjects by group (API endpoint)
     */
    public function getByGroup($groupCode)
    {
        $mapping = ['3' => 'science', '2' => 'commerce', '1' => 'arts', '0' => 'arts'];
        $groupName = $mapping[$groupCode] ?? null;

        if (!$groupName) return response()->json([]);

        $subjects = Subject::active()
            ->fourthSubjects()
            ->forGroup($groupName)
            ->get(['id', 'name', 'code']);

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