<?php

namespace App\Http\Controllers;

use App\Models\CustomerStatement;
use App\Models\Invoice;
use App\Models\InvoiceInstallment;
use App\Models\Payment;
use App\Models\PaymentMethod;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;

class PaymentController extends Controller
{
    /**
     * عرض قائمة المدفوعات.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $user = auth()->user();
        $query = Payment::with(['invoice', 'paymentMethod', 'createdBy']);

        if ($user->isSystemAdmin()) {
            if ($request->has('company_id')) {
                $query->where('company_id', $request->company_id);
            }
        } else {
            $query->where('company_id', $user->company_id);
        }

        $payments = $query->orderBy('payment_date', 'desc')
            ->paginate(15);

        return view('payments.index', compact('payments'));
    }

    /**
     * عرض نموذج إنشاء دفعة جديدة.
     *
     * @param  int  $invoiceId
     * @return \Illuminate\Http\Response
     */
    public function create($invoiceId = null)
    {
        $companyId = auth()->user()->company_id;

        $invoice = null;
        if ($invoiceId) {
            $invoice = Invoice::where('company_id', $companyId)
                ->with(['customer', 'items'])
                ->findOrFail($invoiceId);
        }

        $invoices = Invoice::where('company_id', $companyId)
            ->where('status', '!=', 'paid')
            ->where('status', '!=', 'cancelled')
            ->with('customer')
            ->get();

        $paymentMethods = PaymentMethod::where('company_id', $companyId)
            ->where('is_active', true)
            ->get();

        return view('payments.create', compact('invoice', 'invoices', 'paymentMethods'));
    }

    /**
     * تخزين دفعة جديدة.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'invoice_id' => 'required|exists:invoices,id',
            'payment_method_id' => 'required|integer',
            'amount' => 'required|numeric|min:0.01',
            'payment_date' => 'required|date',
            'reference_number' => 'nullable|string',
            'notes' => 'nullable|string',
            'installment_id' => 'nullable|exists:invoice_installments,id',
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                ->withErrors($validator)
                ->withInput();
        }

        $companyId = auth()->user()->company_id;
        $invoice = Invoice::where('company_id', $companyId)->findOrFail($request->invoice_id);

        // التحقق من أن المبلغ لا يتجاوز المبلغ المستحق
        if ($request->amount > $invoice->due_amount) {
            return redirect()->back()
                ->with('error', 'مبلغ الدفعة يتجاوز المبلغ المستحق للفاتورة')
                ->withInput();
        }

        try {
            DB::beginTransaction();

            // إنشاء الدفعة
            $payment = Payment::create([
                'company_id' => $companyId,
                'invoice_id' => $invoice->id,
                'payment_method_id' => $request->payment_method_id,
                'amount' => $request->amount,
                'payment_date' => $request->payment_date,
                'reference_number' => $request->reference_number,
                'notes' => $request->notes,
                'status' => 'completed',
                'created_by' => auth()->id(),
            ]);

            // إذا كانت الدفعة لقسط محدد
            if ($request->installment_id) {
                $installment = InvoiceInstallment::where('invoice_id', $invoice->id)
                    ->findOrFail($request->installment_id);

                $payment->update([
                    'payable_type' => 'App\\Models\\InvoiceInstallment',
                    'payable_id' => $installment->id,
                ]);

                // تحديث حالة القسط
                $installment->update([
                    'status' => $request->amount >= $installment->amount ? 'paid' : 'partially_paid',
                ]);
            }

            // تحديث الفاتورة
            $invoice->paid_amount += $request->amount;
            $invoice->due_amount -= $request->amount;

            // تحديث حالة الفاتورة
            if ($invoice->due_amount <= 0) {
                $invoice->status = 'paid';
            } else {
                $invoice->status = 'partially_paid';
            }

            $invoice->save();

            // إنشاء سجل في كشف حساب العميل
            CustomerStatement::createForPayment($payment);

            DB::commit();

            return redirect()->route('invoices.show', $invoice->id)
                ->with('success', 'تم تسجيل الدفعة بنجاح');
        } catch (\Exception $e) {
            DB::rollBack();
            return redirect()->back()
                ->with('error', 'حدث خطأ أثناء تسجيل الدفعة: ' . $e->getMessage())
                ->withInput();
        }
    }

    /**
     * عرض دفعة محددة.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $companyId = auth()->user()->company_id;
        $payment = Payment::where('company_id', $companyId)
            ->with(['invoice', 'invoice.customer', 'paymentMethod', 'createdBy'])
            ->findOrFail($id);

        return view('payments.show', compact('payment'));
    }

    /**
     * عرض نموذج تعديل دفعة.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $companyId = auth()->user()->company_id;
        $payment = Payment::where('company_id', $companyId)
            ->with(['invoice', 'paymentMethod'])
            ->findOrFail($id);

        // التحقق من أن الدفعة لم يتم معالجتها بعد
        if ($payment->status !== 'pending') {
            return redirect()->route('payments.show', $payment->id)
                ->with('error', 'لا يمكن تعديل الدفعة لأنها تمت معالجتها بالفعل');
        }

        $paymentMethods = PaymentMethod::where('company_id', $companyId)
            ->where('is_active', true)
            ->get();

        return view('payments.edit', compact('payment', 'paymentMethods'));
    }

    /**
     * تحديث دفعة محددة.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $companyId = auth()->user()->company_id;
        $payment = Payment::where('company_id', $companyId)->findOrFail($id);

        // التحقق من أن الدفعة لم يتم معالجتها بعد
        if ($payment->status !== 'pending') {
            return redirect()->route('payments.show', $payment->id)
                ->with('error', 'لا يمكن تعديل الدفعة لأنها تمت معالجتها بالفعل');
        }

        $validator = Validator::make($request->all(), [
            'payment_method_id' => 'required|integer',
            'amount' => 'required|numeric|min:0.01',
            'payment_date' => 'required|date',
            'reference_number' => 'nullable|string',
            'notes' => 'nullable|string',
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                ->withErrors($validator)
                ->withInput();
        }

        $invoice = $payment->invoice;

        // التحقق من أن المبلغ الجديد لا يتجاوز المبلغ المستحق
        $newDueAmount = $invoice->due_amount + $payment->amount - $request->amount;
        if ($newDueAmount < 0) {
            return redirect()->back()
                ->with('error', 'مبلغ الدفعة يتجاوز المبلغ المستحق للفاتورة')
                ->withInput();
        }

        try {
            DB::beginTransaction();

            // تحديث الدفعة
            $payment->update([
                'payment_method_id' => $request->payment_method_id,
                'amount' => $request->amount,
                'payment_date' => $request->payment_date,
                'reference_number' => $request->reference_number,
                'notes' => $request->notes,
            ]);

            // تحديث الفاتورة
            $invoice->paid_amount = $invoice->paid_amount - $payment->getOriginal('amount') + $request->amount;
            $invoice->due_amount = $invoice->total_amount - $invoice->paid_amount;

            // تحديث حالة الفاتورة
            if ($invoice->due_amount <= 0) {
                $invoice->status = 'paid';
            } else if ($invoice->paid_amount > 0) {
                $invoice->status = 'partially_paid';
            } else {
                $invoice->status = 'sent';
            }

            $invoice->save();

            // تحديث سجل كشف حساب العميل
            $statement = CustomerStatement::where('reference_type', 'App\\Models\\Payment')
                ->where('reference_id', $payment->id)
                ->first();

            if ($statement) {
                $statement->update([
                    'credit' => $request->amount,
                    'balance' => $statement->balance + $statement->credit - $request->amount,
                ]);
            }

            DB::commit();

            return redirect()->route('payments.show', $payment->id)
                ->with('success', 'تم تحديث الدفعة بنجاح');
        } catch (\Exception $e) {
            DB::rollBack();
            return redirect()->back()
                ->with('error', 'حدث خطأ أثناء تحديث الدفعة: ' . $e->getMessage())
                ->withInput();
        }
    }

    /**
     * حذف دفعة محددة.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $companyId = auth()->user()->company_id;
        $payment = Payment::where('company_id', $companyId)->findOrFail($id);

        // التحقق من أن الدفعة لم يتم معالجتها بعد
        if ($payment->status !== 'pending') {
            return redirect()->route('payments.show', $payment->id)
                ->with('error', 'لا يمكن حذف الدفعة لأنها تمت معالجتها بالفعل');
        }

        try {
            DB::beginTransaction();

            // حذف سجل كشف حساب العميل
            CustomerStatement::where('reference_type', 'App\\Models\\Payment')
                ->where('reference_id', $payment->id)
                ->delete();

            // حذف الدفعة
            $payment->delete();

            DB::commit();

            return redirect()->route('payments.index')
                ->with('success', 'تم حذف الدفعة بنجاح');
        } catch (\Exception $e) {
            DB::rollBack();
            return redirect()->back()
                ->with('error', 'حدث خطأ أثناء حذف الدفعة: ' . $e->getMessage());
        }
    }

    /**
     * تغيير حالة الدفعة.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function changeStatus(Request $request, $id)
    {
        $validator = Validator::make($request->all(), [
            'status' => 'required|in:completed,pending,failed,refunded',
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                ->withErrors($validator)
                ->withInput();
        }

        $companyId = auth()->user()->company_id;
        $payment = Payment::where('company_id', $companyId)->findOrFail($id);
        $oldStatus = $payment->status;

        try {
            DB::beginTransaction();

            // تحديث حالة الدفعة
            $payment->update([
                'status' => $request->status,
            ]);

            // إذا تم تغيير الحالة من مكتملة إلى أي حالة أخرى، يجب تحديث الفاتورة
            if ($oldStatus === 'completed' && $request->status !== 'completed') {
                $invoice = $payment->invoice;
                $invoice->paid_amount -= $payment->amount;
                $invoice->due_amount += $payment->amount;

                // تحديث حالة الفاتورة
                if ($invoice->due_amount >= $invoice->total_amount) {
                    $invoice->status = 'sent';
                } else if ($invoice->paid_amount > 0) {
                    $invoice->status = 'partially_paid';
                }

                $invoice->save();
            }
            // إذا تم تغيير الحالة من أي حالة أخرى إلى مكتملة، يجب تحديث الفاتورة
            else if ($oldStatus !== 'completed' && $request->status === 'completed') {
                $invoice = $payment->invoice;
                $invoice->paid_amount += $payment->amount;
                $invoice->due_amount -= $payment->amount;

                // تحديث حالة الفاتورة
                if ($invoice->due_amount <= 0) {
                    $invoice->status = 'paid';
                } else {
                    $invoice->status = 'partially_paid';
                }

                $invoice->save();
            }

            DB::commit();

            return redirect()->route('payments.show', $payment->id)
                ->with('success', 'تم تغيير حالة الدفعة بنجاح');
        } catch (\Exception $e) {
            DB::rollBack();
            return redirect()->back()
                ->with('error', 'حدث خطأ أثناء تغيير حالة الدفعة: ' . $e->getMessage());
        }
    }

    /**
     * طباعة إيصال الدفع.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function receipt($id)
    {
        $companyId = auth()->user()->company_id;
        $payment = Payment::where('company_id', $companyId)
            ->with(['invoice', 'invoice.customer', 'paymentMethod', 'createdBy'])
            ->findOrFail($id);

        return view('payments.receipt', compact('payment'));
    }

    /**
     * طباعة إيصال الدفع.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function printReceipt($id)
    {
        $companyId = auth()->user()->company_id;
        $payment = Payment::where('company_id', $companyId)
            ->with(['invoice', 'invoice.customer', 'paymentMethod', 'createdBy'])
            ->findOrFail($id);

        return view('payments.receipt', compact('payment'));
    }
}
