<?php

namespace MoneyTransfer\Core\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use MoneyTransfer\Core\Models\Transfer;
use MoneyTransfer\Core\Repositories\TransferRepository;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

class TransferController extends Controller
{
    protected $transferRepository;

    public function __construct(TransferRepository $transferRepository)
    {
        $this->transferRepository = $transferRepository;
    }

    public function index(Request $request): JsonResponse
    {
        $perPage = $request->get('per_page', 15);
        $filters = $request->only(['status', 'currency', 'date_from', 'date_to', 'search']);

        $transfers = $this->transferRepository->getTransfersWithFilters($filters, $perPage);

        return response()->json([
            'success' => true,
            'data' => $transfers,
            'message' => 'Transfers retrieved successfully'
        ]);
    }

    public function store(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'recipient_id' => 'required|exists:clients,id',
            'amount' => 'required|numeric|min:1',
            'currency_from' => 'required|string|max:3',
            'currency_to' => 'required|string|max:3',
            'exchange_rate' => 'required|numeric|min:0',
            'fee' => 'required|numeric|min:0',
            'total_amount' => 'required|numeric|min:0',
            'recipient_amount' => 'required|numeric|min:0',
            'transfer_type' => 'required|in:instant,scheduled,recurring',
            'payment_method' => 'required|string',
            'notes' => 'nullable|string|max:500',
            'scheduled_date' => 'nullable|date|after:now',
            'recurring_frequency' => 'nullable|in:daily,weekly,monthly',
            'recurring_end_date' => 'nullable|date|after:now',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $validator->errors()
            ], 422);
        }

        try {
            DB::beginTransaction();

            $transferData = $request->all();
            $transferData['sender_id'] = auth()->id();
            $transferData['reference_number'] = 'TRF-' . strtoupper(Str::random(8));
            $transferData['status'] = 'pending';
            $transferData['transfer_date'] = now();

            if ($request->transfer_type === 'scheduled') {
                $transferData['transfer_date'] = $request->scheduled_date;
                $transferData['status'] = 'scheduled';
            }

            $transfer = $this->transferRepository->create($transferData);

            // Create notification for the transfer
            $this->createTransferNotification($transfer);

            DB::commit();

            return response()->json([
                'success' => true,
                'data' => $transfer->load(['sender', 'recipient', 'currencyFrom', 'currencyTo']),
                'message' => 'Transfer created successfully'
            ], 201);

        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false,
                'message' => 'Failed to create transfer',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    public function show($id): JsonResponse
    {
        $transfer = $this->transferRepository->findById($id);

        if (!$transfer) {
            return response()->json([
                'success' => false,
                'message' => 'Transfer not found'
            ], 404);
        }

        return response()->json([
            'success' => true,
            'data' => $transfer->load(['sender', 'recipient', 'currencyFrom', 'currencyTo', 'recurringTransfers']),
            'message' => 'Transfer retrieved successfully'
        ]);
    }

    public function confirmReceived(Request $request, $id): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'confirmation_method' => 'required|in:bank_transfer,cash_pickup,mobile_money',
            'confirmation_date' => 'required|date',
            'confirmation_notes' => 'nullable|string|max:500',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $validator->errors()
            ], 422);
        }

        try {
            DB::beginTransaction();

            $transfer = $this->transferRepository->findById($id);

            if (!$transfer) {
                return response()->json([
                    'success' => false,
                    'message' => 'Transfer not found'
                ], 404);
            }

            if ($transfer->status !== 'pending') {
                return response()->json([
                    'success' => false,
                    'message' => 'Transfer cannot be confirmed in current status'
                ], 400);
            }

            $transfer->update([
                'status' => 'completed',
                'actual_delivery_date' => $request->confirmation_date,
                'notes' => $transfer->notes . "\n\nConfirmation: " . $request->confirmation_notes,
            ]);

            // Create confirmation notification
            $this->createConfirmationNotification($transfer, $request->all());

            DB::commit();

            return response()->json([
                'success' => true,
                'data' => $transfer->load(['sender', 'recipient']),
                'message' => 'Transfer confirmed successfully'
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false,
                'message' => 'Failed to confirm transfer',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    public function destroy($id): JsonResponse
    {
        $transfer = $this->transferRepository->findById($id);

        if (!$transfer) {
            return response()->json([
                'success' => false,
                'message' => 'Transfer not found'
            ], 404);
        }

        if ($transfer->status !== 'pending') {
            return response()->json([
                'success' => false,
                'message' => 'Cannot delete transfer in current status'
            ], 400);
        }

        $transfer->delete();

        return response()->json([
            'success' => true,
            'message' => 'Transfer deleted successfully'
        ]);
    }

    public function search(Request $request): JsonResponse
    {
        $query = $request->get('q', '');
        $perPage = $request->get('per_page', 15);

        $transfers = $this->transferRepository->search($query, $perPage);

        return response()->json([
            'success' => true,
            'data' => $transfers,
            'message' => 'Search completed successfully'
        ]);
    }

    private function createTransferNotification($transfer)
    {
        // Create notification for the sender
        \MoneyTransfer\Core\Models\Notification::create([
            'user_id' => $transfer->sender_id,
            'type' => 'transfer',
            'title' => 'Transfer Initiated',
            'message' => "Your transfer of {$transfer->amount} {$transfer->currency_from} has been initiated.",
            'data' => [
                'transfer_id' => $transfer->id,
                'amount' => $transfer->amount,
                'currency' => $transfer->currency_from,
            ],
            'priority' => 'medium',
            'action_url' => "/transfers/{$transfer->id}",
        ]);
    }

    private function createConfirmationNotification($transfer, $confirmationData)
    {
        // Create notification for the sender about confirmation
        \MoneyTransfer\Core\Models\Notification::create([
            'user_id' => $transfer->sender_id,
            'type' => 'transfer',
            'title' => 'Transfer Confirmed',
            'message' => "Your transfer has been confirmed by the recipient.",
            'data' => [
                'transfer_id' => $transfer->id,
                'confirmation_method' => $confirmationData['confirmation_method'],
                'confirmation_date' => $confirmationData['confirmation_date'],
            ],
            'priority' => 'high',
            'action_url' => "/transfers/{$transfer->id}",
        ]);
    }
} 