<?php
namespace App\Services;

use App\Repositories\CarRepository;
use App\Repositories\PurchaseRepository;
use App\Repositories\SettingRepository;
use Exception;

class PurchaseService {
    protected $carRepo;
    protected $purchaseRepo;
    protected $settingRepo;
    protected $paymentService;

    public function __construct() {
        $this->carRepo = new CarRepository();
        $this->purchaseRepo = new PurchaseRepository();
        $this->settingRepo = new SettingRepository();
        $this->paymentService = new PaymentService();
    }

    public function reserveCar($carId, $userId) {
        $this->carRepo->beginTransaction();
        try {
            $car = $this->carRepo->find($carId, true); // Lock for update
            
            if (!$car) throw new Exception("Car not found.");
            if ($car['status'] !== 'approved') throw new Exception("Car is not available for sale.");
            if ($car['user_id'] == $userId) throw new Exception("You cannot buy your own car.");
            
            // Check if already reserved by someone else and not expired
            if ($car['reserved_by'] && $car['reserved_by'] != $userId && strtotime($car['reservation_expires_at']) > time()) {
                throw new Exception("This car is currently reserved by another buyer.");
            }

            $this->carRepo->reserve($carId, $userId);
            $this->carRepo->commit();
            return true;
        } catch (Exception $e) {
            $this->carRepo->rollBack();
            throw $e;
        }
    }

    public function calculateFees($price) {
        $feePercent = $this->settingRepo->get('marketplace_fee_percentage', 5);
        $taxPercent = $this->settingRepo->get('tax_percentage', 10);

        $fee = ($price * $feePercent) / 100;
        $tax = ($price * $taxPercent) / 100;
        $total = $price + $fee + $tax;

        return [
            'base_price' => $price,
            'fee' => $fee,
            'tax' => $tax,
            'total' => $total
        ];
    }

    public function initiatePurchase($carId, $userId, $buyerData) {
        $this->purchaseRepo->beginTransaction();
        try {
            $car = $this->carRepo->find($carId, true);
            if (!$car) throw new Exception("Car not found.");

            $costs = $this->calculateFees($car['price']);
            $transactionId = $this->paymentService->generateUUID();
            $ref = $this->purchaseRepo->generateUniqueReference();
            $token = $this->paymentService->generateVerificationToken($transactionId, $costs['total']);

            $purchaseId = $this->purchaseRepo->create([
                'transaction_id' => $transactionId,
                'reference_number' => $ref,
                'verification_token' => $token,
                'car_id' => $carId,
                'user_id' => $userId,
                'buyer_name' => $buyerData['name'],
                'buyer_email' => $buyerData['email'],
                'buyer_phone' => $buyerData['phone'],
                'base_price' => $costs['base_price'],
                'marketplace_fee' => $costs['fee'],
                'tax' => $costs['tax'],
                'total_amount' => $costs['total'],
                'status' => 'initiated',
                'escrow_status' => 'awaiting_verification',
                'payment_method' => $buyerData['payment_method'],
                'expires_at' => date('Y-m-d H:i:s', strtotime("+1 hour"))
            ]);

            $this->purchaseRepo->commit();
            return $transactionId;
        } catch (Exception $e) {
            $this->purchaseRepo->rollBack();
            throw $e;
        }
    }
}