<?php

namespace App\Controllers\Api;

use App\Models\ClaimModel;
use App\Models\ClaimBeneficiaryModel;
use App\Models\MemberModel;
use App\Models\BeneficiaryModel;

class ClaimsController extends ApiController
{
    protected $claimModel;
    protected $claimBeneficiaryModel;
    protected $memberModel;
    protected $beneficiaryModel;

    public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);
        
        try {
            $this->claimModel = new ClaimModel();
            $this->claimBeneficiaryModel = new ClaimBeneficiaryModel();
            $this->memberModel = new MemberModel();
            $this->beneficiaryModel = new BeneficiaryModel();
        } catch (\Exception $e) {
            log_message('error', 'ClaimsController init error: ' . $e->getMessage());
        }
    }

    public function index()
    {
        if (!$this->hasAnyRole(['admin', 'finance'])) {
            return $this->respond(['error' => 'Forbidden'], 403);
        }

        $page = (int) $this->request->getGet('page') ?? 1;
        $limit = (int) $this->request->getGet('limit') ?? 20;
        $status = $this->request->getGet('status');

        $query = $this->claimModel;
        if ($status) {
            $query = $query->where('status', $status);
        }

        $claims = $query->paginate($limit, 'default', $page);

        return $this->respond([
            'claims' => $claims,
            'page' => $page,
            'limit' => $limit,
        ]);
    }

    public function getByMember($memberId)
    {
        if (!$this->isAuthenticated()) {
            return $this->respond(['error' => 'Unauthorized'], 401);
        }

        $member = $this->memberModel->find($memberId);
        if (!$member) {
            return $this->respondNotFound();
        }

        $claims = $this->claimModel->getClaimsByMember($memberId);

        return $this->respond(['claims' => $claims]);
    }

    public function create()
    {
        if (!$this->hasAnyRole(['admin', 'finance'])) {
            return $this->respond(['error' => 'Forbidden'], 403);
        }

        if (!$this->request->is('post')) {
            return $this->respondBadRequest('Invalid request method');
        }

        $data = $this->request->getJSON();

        $member = $this->memberModel->find($data->member_id);
        if (!$member) {
            return $this->respondNotFound();
        }

        $claimNo = $this->claimModel->generateClaimNo();

        $claimData = [
            'member_id' => $data->member_id,
            'claim_type' => $data->claim_type ?? 'death',
            'claim_no' => $claimNo,
            'date_reported' => date('Y-m-d'),
            'date_of_incident' => $data->date_of_incident ?? null,
            'status' => 'submitted',
            'submitted_by' => $this->currentUser['userId'] ?? null,
            'documents' => isset($data->documents) ? json_encode($data->documents) : null,
            'notes' => $data->notes ?? null,
        ];

        if ($this->claimModel->insert($claimData)) {
            $claimId = $this->claimModel->insertID();

            // Add claim beneficiaries
            if (isset($data->beneficiaries) && is_array($data->beneficiaries)) {
                foreach ($data->beneficiaries as $beneficiary) {
                    $beneficiaryData = [
                        'claim_id' => $claimId,
                        'beneficiary_id' => $beneficiary->beneficiary_id,
                        'amount' => $beneficiary->amount,
                        'status' => 'pending',
                    ];
                    $this->claimBeneficiaryModel->insert($beneficiaryData);
                }
            }

            $this->logAudit('create', 'claim', $claimId, null, $claimData);
            return $this->respondCreated([
                'claimId' => $claimId,
                'claim_no' => $claimNo,
                'message' => 'Claim submitted successfully'
            ]);
        }

        return $this->respondBadRequest('Failed to submit claim');
    }

    public function show($id)
    {
        if (!$this->isAuthenticated()) {
            return $this->respond(['error' => 'Unauthorized'], 401);
        }

        $claim = $this->claimModel->find($id);

        if (!$claim) {
            return $this->respondNotFound();
        }

        $beneficiaries = $this->claimBeneficiaryModel->getBeneficiariesByClaimWithDetails($id);

        return $this->respond([
            'claim' => $claim,
            'beneficiaries' => $beneficiaries,
            'total_amount' => $this->claimBeneficiaryModel->getTotalClaimBeneficiaryAmount($id),
            'paid_amount' => $this->claimBeneficiaryModel->getPaidBeneficiaryAmount($id),
        ]);
    }

    public function approve($id)
    {
        if (!$this->hasRole('admin')) {
            return $this->respond(['error' => 'Forbidden'], 403);
        }

        $claim = $this->claimModel->find($id);
        if (!$claim) {
            return $this->respondNotFound();
        }

        $updateData = [
            'status' => 'approved',
            'reviewed_by' => $this->currentUser['userId'],
            'approved_at' => date('Y-m-d H:i:s'),
        ];

        if ($this->claimModel->update($id, $updateData)) {
            $this->logAudit('update', 'claim', $id, $claim, $updateData);
            return $this->respondUpdated(['message' => 'Claim approved successfully']);
        }

        return $this->respondBadRequest('Failed to approve claim');
    }

    public function reject($id)
    {
        if (!$this->hasRole('admin')) {
            return $this->respond(['error' => 'Forbidden'], 403);
        }

        if (!$this->request->is('post')) {
            return $this->respondBadRequest('Invalid request method');
        }

        $claim = $this->claimModel->find($id);
        if (!$claim) {
            return $this->respondNotFound();
        }

        $data = $this->request->getJSON();

        $updateData = [
            'status' => 'rejected',
            'reviewed_by' => $this->currentUser['userId'],
            'rejection_reason' => $data->reason ?? null,
        ];

        if ($this->claimModel->update($id, $updateData)) {
            $this->logAudit('update', 'claim', $id, $claim, $updateData);
            return $this->respondUpdated(['message' => 'Claim rejected']);
        }

        return $this->respondBadRequest('Failed to reject claim');
    }

    public function markAsPaid($id)
    {
        if (!$this->hasRole('finance')) {
            return $this->respond(['error' => 'Forbidden'], 403);
        }

        $claim = $this->claimModel->find($id);
        if (!$claim) {
            return $this->respondNotFound();
        }

        $updateData = [
            'status' => 'paid',
            'paid_at' => date('Y-m-d H:i:s'),
        ];

        if ($this->claimModel->update($id, $updateData)) {
            // Mark all beneficiaries as paid
            $this->db->table('claim_beneficiaries')
                ->where('claim_id', $id)
                ->update(['status' => 'paid']);

            $this->logAudit('update', 'claim', $id, $claim, $updateData);
            return $this->respondUpdated(['message' => 'Claim marked as paid']);
        }

        return $this->respondBadRequest('Failed to mark claim as paid');
    }

    public function getStats()
    {
        if (!$this->hasAnyRole(['admin', 'finance'])) {
            return $this->respond(['error' => 'Forbidden'], 403);
        }

        $year = (int) ($this->request->getGet('year') ?: date('Y'));
        $baseQuery = $this->db->table('claims')->where('YEAR(date_reported)', $year, false);

        $pending = (clone $baseQuery)
            ->groupStart()
            ->where('status', 'submitted')
            ->orWhere('status', 'under_review')
            ->groupEnd()
            ->countAllResults();
        $approved = (clone $baseQuery)
            ->where('status', 'approved')
            ->countAllResults();
        $paid = (clone $baseQuery)
            ->where('status', 'paid')
            ->countAllResults();
        $approvedAmountRow = (clone $baseQuery)
            ->where('status', 'approved')
            ->selectSum('total_amount')
            ->get()
            ->getRowArray();
        $paidAmountRow = (clone $baseQuery)
            ->where('status', 'paid')
            ->selectSum('total_amount')
            ->get()
            ->getRowArray();

        $stats = [
            'year' => $year,
            'pending' => $pending,
            'approved' => $approved,
            'paid' => $paid,
            'total_approved_amount' => (float) ($approvedAmountRow['total_amount'] ?? 0),
            'total_paid_amount' => (float) ($paidAmountRow['total_amount'] ?? 0),
        ];

        return $this->respond($stats);
    }
}
