<?php

namespace App\Http\Controllers;

use App\Exports\BandSaleExport;
use App\Models\BandSale;
use App\Models\BandSaleItem;
use App\Models\BandService;
use App\Models\BwCustomer;
use App\Models\Income;
use App\Models\IncomeHead;
use App\Models\Banking;
use App\Models\BankTransfar;
use App\Services\FundTransferService;
use Barryvdh\DomPDF\Facade\Pdf;
use Brian2694\Toastr\Facades\Toastr;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Maatwebsite\Excel\Facades\Excel;

class BandwdtihSaleController extends Controller
{

    public function index()
    {
        $data = [
            'list' => BandSale::with(['bandwidthSaleCustomer', 'bankAccount'])->get(),
        ];

        return view('bandwidth-sale.bw-sale.index', $data);
    }

    public function create()
    {
        $data = [
            'customer' => BwCustomer::get(),
            'service' => BandService::all(),
            'bankAccounts' => Banking::where('status', 1)->get()
        ];

        return view('bandwidth-sale.bw-sale.create', $data);
    }

    public function store(Request $request)
    {
        // dd($request->all());
        DB::beginTransaction();
        try {

            $bandWidthSale = new BandSale();
            $bandWidthSale->customer_id = $request->customer_id;
            $bandWidthSale->billing_date = Carbon::createFromFormat('m/d/Y', $request->billing_date);
            $bandWidthSale->invoice_no = $request->invoice_no;
            $bandWidthSale->paid = $request->paidAmount;
            $bandWidthSale->discount = $request->discount;
            $bandWidthSale->total = $request->totalPrice;
            $bandWidthSale->bank_account_id = $request->bank_account_id ?? null;
            $bandWidthSale->save();

            $income_amount = 0;
            if (($request->totalPrice - $request->discount) < $request->paidAmount) {
                $income_amount = $request->totalPrice - $request->discount;
            } else {
                $income_amount = $request->paidAmount;
            }

            $len = sizeof($request->service_id);
            for ($i = 0; $i < $len; $i++) {
                $saleItem = new BandSaleItem();
                $saleItem->sale_id = $bandWidthSale->id;
                $saleItem->service_id = $request->service_id[$i];
                $saleItem->from_date = $request->from_date[$i];
                $saleItem->to_date = $request->to_date[$i];
                $saleItem->quantity = $request->quantity[$i];
                $saleItem->rate = $request->rate[$i];
                $saleItem->vat = $request->vat[$i];
                $saleItem->line_total = $request->lineTotal[$i];
                $saleItem->save();
            }

            $income_head = IncomeHead::where('name', "BandWith Sale")->first();
            if ($income_head == null) {
                (new FixCommonIssueController)->addBandwidthSaleInIncomeHeadTable();
                $income_head = IncomeHead::where('name', "BandWith Sale")->first();
            }
            $note = "Bandwidth Sale added by " . auth()->user()->name;
            $income = new Income();
            $income->name = "Bandwidth Sale";
            $income->incomeHead = $income_head->id;
            $income->invoice_number = 'nan';
            $income->date = Carbon::parse($request->billing_date);
            $income->amount = $income_amount;
            $income->description = $note;
            $income->bandwidth_sale_id = $bandWidthSale->id;
            $income->bank_account_id = $request->bank_account_id ?? null;

            $income->save();

            // Check if bank account is selected
            if ($request->filled('bank_account_id')) {
                // Deposit to bank account
                $bankDeposit = new BankTransfar();
                $bankDeposit->account_id = $request->bank_account_id;
                $bankDeposit->diposit_amount = $income_amount;
                // Include sale ID in description for easier matching during updates
                $bankDeposit->description = 'Bandwidth Sale [ID:' . $bandWidthSale->id . ']: Invoice ' . $request->invoice_no . ' - ' . $note;
                $bankDeposit->by = auth()->user()->name ?? 'System';
                $bankDeposit->save();
            }
            // Add to cash (existing behavior)
            // $fundNote = 'Fund Added For: Bandwidth Sale - Invoice ' . $request->invoice_no . ' : ' . $note;
            // (new FundTransferService)->addFundToCash($income_amount, $fundNote, $income->id, 'income');

            DB::commit();
            Toastr::success("Sale successful added");
            return redirect()->route('bw-sale.index');
        } catch (\Exception $e) {
            // dd($e);
            DB::rollBack();
            Toastr::error('Sale is not successful');
            return redirect()->back();
        }
    }

    public function show($id)
    {
        //
    }

    public function edit($id)
    {
        $bandWidthSale = BandSale::with('sateItems')->find($id);
        $data = [
            'bandWidthSale' => $bandWidthSale,
            'customer' => BwCustomer::get(),
            'service' => BandService::all(),
            'bankAccounts' => Banking::where('status', 1)->get()
        ];
        return view('bandwidth-sale.bw-sale.edit', $data);
    }

    public function update(Request $request, $id)
    {
        DB::beginTransaction();
        try {

            $bandWidthSale =  BandSale::find($id);
            $bandWidthSale->customer_id = $request->customer_id;
            $bandWidthSale->billing_date = Carbon::createFromFormat('m/d/Y', $request->billing_date);
            $bandWidthSale->invoice_no = $request->invoice_no;
            $bandWidthSale->paid = $request->paidAmount;
            $bandWidthSale->discount = $request->discount;
            $bandWidthSale->total = $request->totalPrice;
            $bandWidthSale->bank_account_id = $request->bank_account_id ?? null;
            $bandWidthSale->save();

            $income_amount = 0;
            if (($request->totalPrice - $request->discount) < $request->paidAmount) {
                $income_amount = $request->totalPrice - $request->discount;
            } else {
                $income_amount = $request->paidAmount;
            }

            BandSaleItem::where('sale_id', $id)->delete();

            $len = sizeof($request->service_id);
            for ($i = 0; $i < $len; $i++) {
                $saleItem = new BandSaleItem();
                $saleItem->sale_id = $bandWidthSale->id;
                $saleItem->service_id = $request->service_id[$i];
                $saleItem->from_date = $request->from_date[$i];
                $saleItem->to_date = $request->to_date[$i];
                $saleItem->quantity = $request->quantity[$i];
                $saleItem->rate = $request->rate[$i];
                $saleItem->vat = $request->vat[$i];
                $saleItem->line_total = $request->lineTotal[$i];
                $saleItem->save();
            }


            $income =  Income::where('bandwidth_sale_id', $bandWidthSale->id)->first();

            $income->date = Carbon::parse($request->billing_date);
            $income->amount = $income_amount;
            $income->bank_account_id = $request->bank_account_id ?? null;

            $income->save();

            // Check if bank account is selected
            if ($request->filled('bank_account_id')) {
                // Find existing bank deposit for this bandwidth sale by sale ID (most reliable)
                $existingBankDeposit = BankTransfar::where('description', 'like', '%Bandwidth Sale [ID:' . $bandWidthSale->id . ']%')
                    ->whereNotNull('diposit_amount')
                    ->first();

                // Fallback: If not found by ID, try searching by invoice number
                if (!$existingBankDeposit) {
                    $existingBankDeposit = BankTransfar::where('description', 'like', '%Bandwidth Sale%')
                        ->where(function($query) use ($bandWidthSale, $request, $income) {
                            // Match by invoice number (current or from request)
                            $query->where(function($q) use ($bandWidthSale, $request) {
                                $q->where('description', 'like', '%Invoice ' . $bandWidthSale->invoice_no . '%')
                                  ->orWhere('description', 'like', '%Invoice ' . $request->invoice_no . '%');
                            })
                            // Or match by creation time (within 5 minutes of income creation)
                            ->orWhere(function($q) use ($income) {
                                $incomeCreatedAt = $income->created_at;
                                $q->whereBetween('created_at', [
                                    $incomeCreatedAt->copy()->subMinutes(5),
                                    $incomeCreatedAt->copy()->addMinutes(5)
                                ]);
                            });
                        })
                        ->whereNotNull('diposit_amount')
                        ->orderBy('created_at', 'desc')
                        ->first();
                }

                if ($existingBankDeposit) {
                    // Update existing bank deposit - update account even if it changed
                    $existingBankDeposit->account_id = $request->bank_account_id;
                    $existingBankDeposit->diposit_amount = $income_amount;
                    $existingBankDeposit->description = 'Bandwidth Sale [ID:' . $bandWidthSale->id . ']: Invoice ' . $request->invoice_no . ' - Bandwidth Sale added by ' . auth()->user()->name;
                    $existingBankDeposit->by = auth()->user()->name ?? 'System';
                    $existingBankDeposit->save();
                } else {
                    // Create new bank deposit
                    $bankDeposit = new BankTransfar();
                    $bankDeposit->account_id = $request->bank_account_id;
                    $bankDeposit->diposit_amount = $income_amount;
                    $bankDeposit->description = 'Bandwidth Sale [ID:' . $bandWidthSale->id . ']: Invoice ' . $request->invoice_no . ' - Bandwidth Sale added by ' . auth()->user()->name;
                    $bankDeposit->by = auth()->user()->name ?? 'System';
                    $bankDeposit->save();
                }
            }

            // else {
            //     // If bank account is not selected, find and delete any existing bank deposit for this sale
            //     // First try by sale ID
            //     $depositsToDelete = BankTransfar::where('description', 'like', '%Bandwidth Sale [ID:' . $bandWidthSale->id . ']%')
            //         ->whereNotNull('diposit_amount')
            //         ->get();

            //     // Fallback: If not found by ID, try by invoice number or creation time
            //     if ($depositsToDelete->isEmpty()) {
            //         $depositsToDelete = BankTransfar::where('description', 'like', '%Bandwidth Sale%')
            //             ->where(function($query) use ($bandWidthSale, $request, $income) {
            //                 $query->where(function($q) use ($bandWidthSale, $request) {
            //                     $q->where('description', 'like', '%Invoice ' . $bandWidthSale->invoice_no . '%')
            //                       ->orWhere('description', 'like', '%Invoice ' . $request->invoice_no . '%');
            //                 })
            //                 ->orWhere(function($q) use ($income) {
            //                     $incomeCreatedAt = $income->created_at;
            //                     $q->whereBetween('created_at', [
            //                         $incomeCreatedAt->copy()->subMinutes(5),
            //                         $incomeCreatedAt->copy()->addMinutes(5)
            //                     ]);
            //                 });
            //             })
            //             ->whereNotNull('diposit_amount')
            //             ->get();
            //     }

            //     foreach ($depositsToDelete as $deposit) {
            //         $deposit->delete();
            //     }
            // }

            DB::commit();
            Toastr::success("Sale update successful");
            return redirect()->back();
        } catch (\Exception $e) {
            // dd($e);
            DB::rollBack();
            Toastr::error('Sale update is not successful');
            return redirect()->back();
        }
    }

    public function destroy($id)
    {
        //
    }

    public function bandwidthSaleReport()
    {
        $start = today()->firstOfMonth();
        $end = today();

        return view('bandwidth-sale.search', [
            'page_title' => 'Bandwidth Sale Report',
            'start'      => $start,
            'end'        => $end,
            'services'   => BandService::all(),
            'customer' => BwCustomer::get(),
        ]);
    }

    public function bandwidthSaleSearch(Request $request)
    {
        if ($request->ajax()) {

            $from = $request->from_date == '' ? today() : Carbon::parse($request->from_date);
            $to   = $request->to_date == '' ? today() : Carbon::parse($request->to_date);

            $from = Carbon::parse($from)->format('Y-m-d 00:00:00');
            $to   = Carbon::parse($to)->format('Y-m-d 23:59:59');
            $list = BandSale::with('sateItems')->whereBetween('billing_date', [$from, $to]);

            if ($request->company != null) {
                $list->where('customer_id', $request->company);
            }

            if ($request->service != null) {
                $list->whereHas('sateItems', function ($query) use ($request) {
                    $query->where('service_id', $request->service);
                });
            }

            return view('bandwidth-sale.result', [
                'list'       =>  $list->get()
            ]);
        }
    }

    public function downloadSinglePDF($id)
    {
        $invoice = BandSale::with('sateItems')->find($id);

        if (!$invoice) {
            abort(404, 'Invoice not found.');
        }

        $pdf = Pdf::loadView('bandwidth-sale.bw-sale.saleInvoice', compact('invoice'));
        return $pdf->download("invoice-{$invoice->id}.pdf");
    }

    public function bandwidthSaleExport(Request $request)
    {
        $from = $request->from_date == '' ? today() : Carbon::parse($request->from_date);
        $to   = $request->to_date == '' ? today() : Carbon::parse($request->to_date);

        $from = Carbon::parse($from)->format('Y-m-d 00:00:00');
        $to   = Carbon::parse($to)->format('Y-m-d 23:59:59');

        $query = BandSale::with(['sateItems.service', 'bandwidthSaleCustomer'])
            ->whereBetween('billing_date', [$from, $to]);

        if ($request->company) {
            $query->where('customer_id', $request->company);
        }

        if ($request->service) {
            $query->whereHas('sateItems', function ($q) use ($request) {
                $q->where('service_id', $request->service);
            });
        }

        $data = $query->get();

        return Excel::download(new BandSaleExport($data), 'bandwidth_sale_report_' . date('d_m_Y') . '.xlsx');
    }
}
