<?php

namespace App\Http\Controllers\Admin\Finance\Audit;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\InternalAudit;
use App\Models\InternalAuditFinding;
use App\Models\ExternalAudit;
use App\Models\ComplianceCase;
use App\Models\SoxControl;
use App\Models\RiskAssessment;
use App\Models\AccessControl;

class AuditController extends Controller
{
    public function internalAudit(Request $request)
    {
        $q = InternalAudit::query();
        if ($request->filled('status')) $q->where('status', $request->status);
        if ($request->filled('start_date')) $q->whereDate('audit_date', '>=', $request->start_date);
        if ($request->filled('end_date')) $q->whereDate('audit_date', '<=', $request->end_date);
        if ($request->filled('q')) {
            $term = $request->q;
            $q->where(function($w) use ($term){
                $w->where('title','like',"%$term%")
                  ->orWhere('scope','like',"%$term%");
            });
        }
        $audits = $q->orderByDesc('audit_date')->paginate(15)->appends($request->query());
        return view('admin.finance.audit.internal-audit', compact('audits'));
    }

    public function storeInternalAudit(Request $request)
    {
        $validated = $request->validate([
            'title' => 'required|string',
            'scope' => 'nullable|string',
            'audit_date' => 'required|date',
            'auditor' => 'nullable|string',
            'notes' => 'nullable|string',
        ]);
        $validated['status'] = 'open';
        InternalAudit::create($validated);
        return back()->with('success','Internal audit created');
    }

    public function showInternalAudit(InternalAudit $audit)
    {
        $findings = $audit->findings()->latest()->paginate(20);
        return view('admin.finance.audit.internal-audit-show', compact('audit','findings'));
    }

    public function updateInternalAudit(Request $request, InternalAudit $audit)
    {
        $validated = $request->validate([
            'title' => 'required|string',
            'scope' => 'nullable|string',
            'audit_date' => 'required|date',
            'auditor' => 'nullable|string',
            'status' => 'required|in:open,in_progress,closed',
            'notes' => 'nullable|string',
        ]);
        $audit->update($validated);
        return back()->with('success','Audit updated');
    }

    public function destroyInternalAudit(InternalAudit $audit)
    {
        $audit->delete();
        return redirect()->route('admin.finance.audit.internal-audit')->with('success','Audit deleted');
    }

    public function storeFinding(Request $request, InternalAudit $audit)
    {
        $validated = $request->validate([
            'title' => 'required|string',
            'detail' => 'nullable|string',
            'severity' => 'required|in:low,medium,high,critical',
        ]);
        $audit->findings()->create($validated + ['resolved'=>false]);
        return back()->with('success','Finding added');
    }

    public function resolveFinding(InternalAuditFinding $finding, Request $request)
    {
        $finding->update([
            'resolved' => true,
            'resolved_at' => now(),
            'resolution_notes' => $request->input('resolution_notes'),
        ]);
        return back()->with('success','Finding resolved');
    }

    public function externalAudit(Request $request)
    {
        $q = ExternalAudit::query();
        if ($request->filled('status')) $q->where('status', $request->status);
        if ($request->filled('start_date')) $q->whereDate('audit_date', '>=', $request->start_date);
        if ($request->filled('end_date')) $q->whereDate('audit_date', '<=', $request->end_date);
        if ($request->filled('q')) {
            $term = $request->q;
            $q->where(function($w) use ($term){
                $w->where('title','like',"%$term%")
                  ->orWhere('auditor','like',"%$term%")
                  ->orWhere('firm','like',"%$term%");
            });
        }
        $audits = $q->orderByDesc('audit_date')->paginate(15)->appends($request->query());
        return view('admin.finance.audit.external-audit', compact('audits'));
    }

    public function storeExternalAudit(Request $request)
    {
        $validated = $request->validate([
            'title' => 'required|string',
            'auditor' => 'nullable|string',
            'firm' => 'nullable|string',
            'audit_date' => 'required|date',
            'notes' => 'nullable|string',
        ]);
        $validated['status'] = 'open';
        ExternalAudit::create($validated);
        return back()->with('success','External audit created');
    }

    public function updateExternalAudit(Request $request, ExternalAudit $audit)
    {
        $validated = $request->validate([
            'title' => 'required|string',
            'auditor' => 'nullable|string',
            'firm' => 'nullable|string',
            'audit_date' => 'required|date',
            'status' => 'required|in:open,in_progress,closed',
            'notes' => 'nullable|string',
        ]);
        $audit->update($validated);
        return back()->with('success','External audit updated');
    }

    public function destroyExternalAudit(ExternalAudit $audit)
    {
        $audit->delete();
        return back()->with('success','External audit deleted');
    }

    public function compliance()
    {
        $cases = ComplianceCase::latest()->paginate(15);
        return view('admin.finance.audit.compliance', compact('cases'));
    }

    public function sox()
    {
        $controls = SoxControl::latest()->paginate(15);
        return view('admin.finance.audit.sox', compact('controls'));
    }

    public function riskAssessment()
    {
        $risks = RiskAssessment::latest()->paginate(15);
        return view('admin.finance.audit.risk-assessment', compact('risks'));
    }

    public function accessControls()
    {
        $accessControls = AccessControl::latest()->paginate(15);
        return view('admin.finance.audit.access-controls', compact('accessControls'));
    }

    // Compliance CRUD
    public function storeCompliance(Request $request)
    {
        $validated = $request->validate([
            'title' => 'required|string',
            'regulation' => 'nullable|string',
            'due_date' => 'nullable|date',
            'owner' => 'nullable|string',
            'notes' => 'nullable|string',
        ]);
        $validated['status'] = 'open';
        ComplianceCase::create($validated);
        return back()->with('success','Compliance case created');
    }

    public function updateCompliance(Request $request, ComplianceCase $case)
    {
        $validated = $request->validate([
            'title' => 'required|string',
            'regulation' => 'nullable|string',
            'due_date' => 'nullable|date',
            'owner' => 'nullable|string',
            'status' => 'required|in:open,in_progress,closed',
            'notes' => 'nullable|string',
        ]);
        $case->update($validated);
        return back()->with('success','Compliance case updated');
    }

    public function destroyCompliance(ComplianceCase $case)
    {
        $case->delete();
        return back()->with('success','Compliance case deleted');
    }

    // SOX Controls CRUD
    public function storeSox(Request $request)
    {
        $validated = $request->validate([
            'control_name' => 'required|string',
            'framework' => 'nullable|string',
            'owner' => 'nullable|string',
            'test_date' => 'nullable|date',
            'notes' => 'nullable|string',
        ]);
        $validated['status'] = 'active';
        SoxControl::create($validated);
        return back()->with('success','Control created');
    }

    public function updateSox(Request $request, SoxControl $control)
    {
        $validated = $request->validate([
            'control_name' => 'required|string',
            'framework' => 'nullable|string',
            'owner' => 'nullable|string',
            'status' => 'required|in:active,inactive,deprecated',
            'test_date' => 'nullable|date',
            'notes' => 'nullable|string',
        ]);
        $control->update($validated);
        return back()->with('success','Control updated');
    }

    public function destroySox(SoxControl $control)
    {
        $control->delete();
        return back()->with('success','Control deleted');
    }

    // Risk Assessments CRUD
    public function storeRisk(Request $request)
    {
        $validated = $request->validate([
            'title' => 'required|string',
            'area' => 'nullable|string',
            'owner' => 'nullable|string',
            'risk_level' => 'required|in:low,medium,high,critical',
            'assessment_date' => 'nullable|date',
            'mitigation_plan' => 'nullable|string',
        ]);
        $validated['status'] = 'open';
        RiskAssessment::create($validated);
        return back()->with('success','Risk assessment created');
    }

    public function updateRisk(Request $request, RiskAssessment $risk)
    {
        $validated = $request->validate([
            'title' => 'required|string',
            'area' => 'nullable|string',
            'owner' => 'nullable|string',
            'risk_level' => 'required|in:low,medium,high,critical',
            'status' => 'required|in:open,in_progress,mitigated',
            'assessment_date' => 'nullable|date',
            'mitigation_plan' => 'nullable|string',
        ]);
        $risk->update($validated);
        return back()->with('success','Risk assessment updated');
    }

    public function destroyRisk(RiskAssessment $risk)
    {
        $risk->delete();
        return back()->with('success','Risk assessment deleted');
    }

    // Access Controls CRUD
    public function storeAccessControl(Request $request)
    {
        $validated = $request->validate([
            'title' => 'required|string',
            'owner' => 'nullable|string',
            'review_date' => 'nullable|date',
            'notes' => 'nullable|string',
        ]);
        $validated['status'] = 'active';
        AccessControl::create($validated);
        return back()->with('success','Access control created');
    }

    public function updateAccessControl(Request $request, AccessControl $access)
    {
        $validated = $request->validate([
            'title' => 'required|string',
            'owner' => 'nullable|string',
            'status' => 'required|in:active,inactive',
            'review_date' => 'nullable|date',
            'notes' => 'nullable|string',
        ]);
        $access->update($validated);
        return back()->with('success','Access control updated');
    }

    public function destroyAccessControl(AccessControl $access)
    {
        $access->delete();
        return back()->with('success','Access control deleted');
    }

}
