<?php

namespace App\Http\Controllers;

use App\Helpers\Helper;
use App\Models\Payment;
use App\Models\Transaction;
use App\Services\PaymentService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class TransactionController extends Controller
{
    use Helper;

    public function __construct()
    {
        $this->model = new Transaction();
    }

    public function index()
    {
        $keyword = input('name');
        $end_date = input('end_date');
        $start_date = input('start_date');
        $user_id = input('user_id');
        $user = auth()->user();

        $data = $this->model->with(['users:id,name', 'payment.package'])
            ->orderBy('id', 'desc')
            ->when(!$user->is_superadmin, function ($query) use ($user) {
                $query->where('user_id', $user->id);
            })
            ->when($keyword || $user_id, function ($query) use ($keyword, $user_id) {
                $query->whereHas('users', function ($query) use ($keyword, $user_id) {
                    if ($keyword) {
                        $query->where('name', 'LIKE', "%$keyword%");
                    }
                    if ($user_id) {
                        $query->where('id', $user_id);
                    }
                });
            })
            ->when(($start_date || $end_date), function ($query) use ($start_date, $end_date) {
                if ($start_date) {
                    $query->where('created_at', '>=', $start_date);
                }
                if ($end_date) {
                    $query->where('created_at', '<=', $end_date);
                }
            })
            ->paginate(request()->input('perPage', $this->perPage));

        return returnData(2000, $data);
    }

    public function store(Request $request)
    {
        try {
            $paymentId = $request->input('payment_id');
            $status = (int) $request->input('status', 1);
            $userId = (int) $request->input('user_id', auth()->id());
            $requestAmount = (float) $request->input('request_amount', 0);
            $adjustmentAmount = (int) $request->input('adjustment_amount', 0);
            $comment = $request->input('comment', 'Payment approved');
            $expiredDate = $request->input('expired_date');

            if ($paymentId) {
                $payment = Payment::find($paymentId);
                if ($payment) {
                    if ($status === 1) {
                        // Approve payment & activate package
                        $result = PaymentService::approvePayment(
                            $payment,
                            $requestAmount ?: $payment->request_amount,
                            auth()->id(),
                            $comment,
                            $expiredDate,
                            $adjustmentAmount
                        );
                        return returnData(2000, $result, 'Payment Successfully Approved & Package Activated');
                    } else {
                        // Decline payment
                        $result = PaymentService::declinePayment($payment, auth()->id(), $comment);
                        return returnData(2000, $result, 'Payment Request Declined');
                    }
                }
            }

            // Direct transaction creation without payment_id
            DB::beginTransaction();

            $duePayments = Payment::where('user_id', $userId)
                ->where('payement_type', Payment::TYPE_DUE_ADVANCED)
                ->where('due_amount', '>', 0)
                ->orderBy('id', 'asc')
                ->get();

            $remaining = $requestAmount;

            if ($adjustmentAmount == 1 && $duePayments->count() > 0) {
                foreach ($duePayments as $item) {
                    if ($remaining <= 0) break;

                    if ($item->due_amount >= $remaining) {
                        $item->due_amount -= $remaining;
                        $item->save();
                        $remaining = 0;
                    } else {
                        $remaining -= $item->due_amount;
                        $item->due_amount = 0;
                        $item->save();
                    }
                }
            }

            $transaction = Transaction::create([
                'user_id' => $userId,
                'payment_id' => null,
                'request_amount' => $adjustmentAmount == 1 ? $remaining : $requestAmount,
                'comment' => $comment,
                'expired_date' => $expiredDate,
                'sender_types' => $request->input('sender_types', 1),
                'date' => now(),
            ]);

            DB::commit();

            return returnData(2000, $transaction, 'Transaction Successfully Inserted');
        } catch (\Exception $exception) {
            DB::rollback();
            return returnData(5000, $exception->getMessage(), $exception->getMessage());
        }
    }

    public function show($id)
    {
        $data = $this->model->with(['users:id,name', 'payments', 'payment.package'])
            ->where('user_id', $id)
            ->orderBy('id', 'desc')
            ->get();

        return returnData(2000, $data);
    }

    public function invoiceGenerate(Request $request)
    {
        try {
            $id = $request->input('id');
            $data = DB::table('transactions')
                ->leftJoin('payments', 'transactions.payment_id', '=', 'payments.id')
                ->leftJoin('users', 'transactions.user_id', '=', 'users.id')
                ->leftJoin('pricings', 'payments.package_id', '=', 'pricings.id')
                ->select(
                    'transactions.*',
                    'payments.payement_method',
                    'payments.payement_type',
                    'payments.transaction_id',
                    'payments.sender_types',
                    'pricings.title as package_title',
                    'users.name as user_name',
                    'users.masking_rate',
                    'users.company_name',
                    'users.address',
                    'users.email',
                    'users.contact_number',
                    'users.non_masking_rate'
                )
                ->where('transactions.id', $id)
                ->first();

            if (!$data) {
                return abort(404, 'Invoice not found');
            }

            $rate = 0;
            if ($data->sender_types == 1) {
                $rate = $data->masking_rate ?: 0.50;
            } else {
                $rate = $data->non_masking_rate ?: 0.30;
            }
            $totalSms = $rate > 0 ? round($data->request_amount / $rate) : 0;

            $data->total_sms = $totalSms;
            $data->sms_rate_used = $rate;

            $paymentMethods = [
                1 => 'Cash',
                2 => 'bKash',
                3 => 'Bank',
                4 => 'Nagad',
                5 => 'Rocket',
                6 => 'Online Automatic',
            ];

            $data->payment_method_text = $paymentMethods[$data->payement_method] ?? 'N/A';
            $data->sms_type_text = $data->sender_types == 1 ? 'Masking' : 'Non-Masking';

            return view('paymentInvoice', compact('data'));
        } catch (\Exception $e) {
            return returnData(5000, $e->getMessage(), $e->getMessage());
        }
    }
}
