<?php

namespace App\Controllers\Api;

use App\Models\PaymentAnnualModel;
use App\Models\MemberModel;

class PaymentsController extends ApiController
{
    protected $paymentAnnualModel;
    protected $memberModel;

    public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);
        
        try {
            $this->paymentAnnualModel = new PaymentAnnualModel();
            $this->memberModel = new MemberModel();
        } catch (\Exception $e) {
            log_message('error', 'PaymentsController 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->paymentAnnualModel;
        $query = $query->where('fee_type', PaymentAnnualModel::VISIBLE_FEE_TYPE);
        if ($status) {
            if (strtoupper($status) === 'PAID') {
                $query = $query->where('paystatus', 'PAID');
            } else {
                $query = $query->groupStart()
                    ->where('paystatus !=', 'PAID')
                    ->orWhere('paystatus', null)
                    ->groupEnd();
            }
        }

        $invoices = $query->orderBy('fee_year', 'DESC')
            ->orderBy('id', 'DESC')
            ->paginate($limit, 'default', $page);

        return $this->respond([
            'invoices' => $invoices,
            '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();
        }

        $invoices = $this->paymentAnnualModel->getInvoiceByMember($memberId);

        return $this->respond([
            'invoices' => $invoices,
            'total_paid' => $this->paymentAnnualModel->getTotalPaidByMember($memberId),
            'total_outstanding' => $this->paymentAnnualModel->getTotalOutstandingByMember($memberId),
        ]);
    }

    public function create()
    {
        if (!$this->hasRole('admin')) {
            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();
        }

        $referenceNo = $this->paymentAnnualModel->generateReferenceNo();

        $paymentData = [
            'member_id' => $data->member_id,
            'fee_year' => $data->fee_year ?? date('Y'),
            'reference_no' => $referenceNo,
            'fee_type' => $data->fee_type ?? 'AWTF',
            'account' => $data->account ?? null,
            'fee' => $data->fee ?? 50000,
            'paystatus' => 'PENDING',
            'created_at' => date('Y-m-d H:i:s'),
            'duedate' => $data->duedate ?? date('Y-m-d', strtotime('+30 days')),
            'invoice_group' => $data->invoice_group ?? null,
            'installment' => $data->installment ?? 0,
        ];

        if ($this->paymentAnnualModel->insert($paymentData)) {
            $invoiceId = $this->paymentAnnualModel->insertID();
            $this->logAudit('create', 'payment_annual', $invoiceId, null, $paymentData);
            return $this->respondCreated([
                'invoiceId' => $invoiceId,
                'reference_no' => $referenceNo,
                'message' => 'Invoice created successfully'
            ]);
        }

        return $this->respondBadRequest('Failed to create invoice');
    }

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

        $invoice = $this->paymentAnnualModel->find($id);

        if (!$invoice || ($invoice['fee_type'] ?? null) !== PaymentAnnualModel::VISIBLE_FEE_TYPE) {
            return $this->respondNotFound();
        }

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

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

        $invoice = $this->paymentAnnualModel->find($id);
        if (!$invoice || ($invoice['fee_type'] ?? null) !== PaymentAnnualModel::VISIBLE_FEE_TYPE) {
            return $this->respondNotFound();
        }

        // Generate QR code data (simplified)
        $qrData = json_encode([
            'reference' => $invoice['reference_no'],
            'amount' => $invoice['fee'],
            'member' => $invoice['member_id'],
        ]);

        return $this->respond([
            'qr_code' => $qrData,
            'message' => 'QR code generated'
        ]);
    }

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

        $invoice = $this->paymentAnnualModel->find($id);
        if (!$invoice || ($invoice['fee_type'] ?? null) !== PaymentAnnualModel::VISIBLE_FEE_TYPE) {
            return $this->respondNotFound();
        }

        $updateData = ['paystatus' => 'PAID'];
        $this->paymentAnnualModel->update($id, $updateData);
        $this->logAudit('update', 'payment_annual', $id, $invoice, $updateData);

        return $this->respondUpdated(['message' => 'Invoice marked as paid']);
    }

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

        $outstanding = $this->paymentAnnualModel->getOutstandingInvoices();

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

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

        $year = (int) ($this->request->getGet('year') ?: date('Y'));

        $totalInvoicedRow = $this->db->table('payment_annual')
            ->where('fee_type', PaymentAnnualModel::VISIBLE_FEE_TYPE)
            ->where('fee_year', $year)
            ->selectSum('fee')
            ->get()
            ->getRowArray();
        $totalPaidRow = $this->db->table('payment_annual')
            ->where('fee_type', PaymentAnnualModel::VISIBLE_FEE_TYPE)
            ->where('fee_year', $year)
            ->where('paystatus', 'PAID')
            ->selectSum('fee')
            ->get()
            ->getRowArray();
        $totalOutstandingRow = $this->db->table('payment_annual')
            ->where('fee_type', PaymentAnnualModel::VISIBLE_FEE_TYPE)
            ->where('fee_year', $year)
            ->groupStart()
            ->where('paystatus !=', 'PAID')
            ->orWhere('paystatus', null)
            ->groupEnd()
            ->selectSum('fee')
            ->get()
            ->getRowArray();

        $totalInvoiced = (float) ($totalInvoicedRow['fee'] ?? 0);
        $totalPaid = (float) ($totalPaidRow['fee'] ?? 0);
        $totalOutstanding = (float) ($totalOutstandingRow['fee'] ?? 0);

        return $this->respond([
            'year' => $year,
            'total_invoiced' => $totalInvoiced,
            'total_paid' => $totalPaid,
            'total_outstanding' => $totalOutstanding,
            'paid_percentage' => ($totalInvoiced > 0) ? round(($totalPaid / $totalInvoiced) * 100, 2) : 0,
        ]);
    }
}
