<?php

namespace App\Http\Controllers\Admin;

use App\DataTables\CustomerDataTable;
use App\DataTables\CustomerListDataTable;
use App\Http\Controllers\Controller;
use App\Models\Area;
use App\Models\Customer;
use App\Models\PaymentTransaction;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Validator;

class CustomerController extends Controller
{  

    public function index(Request $request, CustomerDataTable $dataTable)
    {
        abort_if(Gate::denies('customer_access'), Response::HTTP_FORBIDDEN, '403 Forbidden');        
        $areas = Area::pluck('address','id');
        return $dataTable->render('admin.customer.index',compact('areas'));
    }

    public function create()
    {
        abort_if(Gate::denies('customer_create'), Response::HTTP_FORBIDDEN, '403 Forbidden');    
        $areas =  Area::orderBy('address')->get();
        $htmlView = view('admin.customer.create',compact('areas'))->render();
        return response()->json(['success' => true, 'htmlView' => $htmlView]);
    }

    public function store(Request $request)
    {
        abort_if(Gate::denies('customer_create'), Response::HTTP_FORBIDDEN, '403 Forbidden');

        $rules = [
            'name'   => ['required','string','max:250'],
            'phone_number'  => ['required','numeric','digits_between:7,10','unique:customers,phone_number'],
            'alternate_phone_number' => ['nullable','numeric','digits_between:7,10','different:phone_number'],
            'area_id'      => ['required','numeric'],
            'remark'      => ['nullable','string'],
            'credit_limit' => ['nullable','numeric','regex:/^\d{1,15}$/'],
        ];

        $request->validate($rules,[],[
            'area_id' => 'area'
        ]);  

        $customer =  Customer::create($request->all());
        addToLog($request,'Customer','Create', $customer);          
        return response()->json(['success' => true,
        'message' => trans('messages.crud.add_record'),
        'alert-type'=> trans('quickadmin.alert-type.success'),
        'title' => trans('quickadmin.customers.customer'),
        ], 200);
    }

    public function edit(Customer $customer)
    {   
        abort_if(Gate::denies('customer_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
        $areas =  Area::orderBy('address')->get();       
        $htmlView = view('admin.customer.edit',compact('areas','customer'))->render();
        return response()->json(['success' => true, 'htmlView' => $htmlView]);
    }


    public function update(Request $request, Customer $customer)
    {
        abort_if(Gate::denies('customer_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');

        $rules = [
            'name'   => ['required','string','max:250'],
            'phone_number'  => ['required','numeric','digits_between:7,10','unique:customers,phone_number,'. $customer->id],
            'alternate_phone_number' => ['nullable','numeric','digits_between:7,10','different:phone_number'],
            'area_id'      => ['required','numeric'],
            // 'remark'      => ['required','string'],
            'credit_limit' => ['nullable','numeric'],
        ];

        $request->validate($rules,[],[
            'area_id' => 'area'
        ]); 
        
        $oldvalue = $customer->getOriginal();        
        $customer->update($request->all());   
        $newValue = $customer->fresh(); 
       
        addToLog($request,'Customer','Edit', $newValue ,$oldvalue);
        return response()->json(['success' => true,
        'message' => trans('messages.crud.update_record'),
        'alert-type'=> trans('quickadmin.alert-type.success'),
        'title' => trans('quickadmin.customers.customer'),
        ], 200);
    }
    

    public function destroy(Request $request, Customer $customer)
    {
        abort_if(Gate::denies('customer_delete'), Response::HTTP_FORBIDDEN, '403 Forbidden');    
        addToLog($request,'Customer','Delete', $customer);
        $customer->delete();
        return response()->json(['success' => true,
         'message' => trans('messages.crud.delete_record'),
         'alert-type'=> trans('quickadmin.alert-type.success'),
         'title' => trans('quickadmin.customers.customer')
        ], 200);
    }

    public function allCustomerPrintView(Request $request)
    {
        abort_if(Gate::denies('customer_print'), Response::HTTP_FORBIDDEN, '403 Forbidden');
        
        $query = Customer::query();
        $areaNames = [];

        if(request()->has('area_id') && !empty(request()->area_id))
        {
            $area_ids = explode(',', request()->area_id);
            $area_ids = array_map('intval', $area_ids);
            $query->whereIn('area_id', $area_ids);
            $areaNames = Area::whereIn('id', $area_ids)->pluck('address')->toArray();
        }

        if(request()->has('customer_id') && !empty(request()->customer_id))
        {
            $customer_ids = explode(',', request()->customer_id);
            $customer_ids = array_map('intval', $customer_ids);
            $query->whereIn('id', $customer_ids);
        }

        // $listtype = isset(request()->listtype) && request()->listtype ? $request->listtype  : 'ledger';
        $listtype = 'all';
        switch ($listtype) {           
            case 'ledger':
                $query = $query->newQuery()
                ->select('customers.*')
                ->whereExists(function ($query) {
                    $query->selectRaw("SUM(CASE WHEN payment_type='debit' THEN amount ELSE 0 END) AS total_debit_amount")
                        ->selectRaw("SUM(CASE WHEN payment_type='credit' THEN amount ELSE 0 END) AS total_credit_amount")
                        ->selectRaw("SUM(CASE WHEN payment_type = 'debit' THEN amount ELSE 0 END) - SUM(CASE WHEN payment_type = 'credit' THEN amount ELSE 0 END) AS total_balance")
                        ->from('payment_transactions')
                        ->whereColumn('payment_transactions.customer_id', 'customers.id')
                        ->whereNull('payment_transactions.deleted_at')
                        ->groupBy('payment_transactions.customer_id')
                        ->havingRaw('total_balance != 0');
                });

                break;
            case 'all':
                $query = $query->newQuery()->select(['customers.*'])/* ->orderBy('Name','ASC') */;
                break;
            default:
            return abort(404);
            break;
        }
        $allcustomers = $query->orderBy('name')->with('area')->get();        
        return view('admin.customer.print-customer-list',compact('allcustomers','areaNames'))->render();
    }

    public function show(Request $request){
        return view('admin.customer.show');
    }

    
    public function allMonthDetail(Request $request,$uuid)
    {
        abort_if(Gate::denies('customer_access'), Response::HTTP_FORBIDDEN, '403 Forbidden');
        $customer = Customer::where('uuid',$request->uuid)->firstOrFail();
       
        $customerCreatedAtYear = Carbon::createFromFormat('Y-m-d H:i:s', $customer->created_at)->year;
        $currentYear = Carbon::now()->year;
        $yearlist = range(2021, $currentYear);
        $currentMonth = Carbon::now()->month;
        $year = $request->year ?? $currentYear;
        $customerCreatedAtMonth = Carbon::createFromFormat('Y-m-d H:i:s', $customer->created_at)->month;
        if ($year == $customerCreatedAtYear)
        {
            $startDate = Carbon::create($year,$customerCreatedAtMonth, 1)->startOfMonth();
        }
        elseif($year < $customerCreatedAtYear){
            $startDate = Carbon::create($customerCreatedAtYear,1, 1)->startOfMonth();
        }
        else{
            $startDate = Carbon::create($year,1, 1)->startOfMonth();
        }

        $endDate = ($year == $currentYear) ? Carbon::create($year, $currentMonth, 1)->endOfMonth() : Carbon::create($year, 12, 1)->endOfMonth();
        $openingBalance = GetYearOpeningBalance($customer->id,$year);       
        
        $estimateData = PaymentTransaction::selectRaw("SUM(amount) as total_amount, DATE_FORMAT(entry_date, '%Y-%m') as month, 'sales' as type")
        ->where('customer_id', $customer->id)
        ->where('payment_way', 'order_create')
        ->whereBetween('entry_date', [$startDate, $endDate])
        ->groupBy(DB::raw("DATE_FORMAT(entry_date, '%Y-%m')"), 'type')
        ->get();
       
        $cashReceiptData = PaymentTransaction::selectRaw("SUM(amount) as total_amount, DATE_FORMAT(entry_date, '%Y-%m') as month, 'cashreceipt' as type")
        ->where('customer_id', $customer->id)
        ->whereIn('payment_way', ['by_cash', 'by_check', 'by_account'])
        ->whereNotNull('voucher_number')
        ->where('remark', '!=', 'Opening balance')
        ->whereBetween('entry_date', [$startDate, $endDate])
        ->groupBy(DB::raw("DATE_FORMAT(entry_date, '%Y-%m')"), 'type')
        ->get();     
                
        $monthlyData = [];
        $currentMonth = $startDate->copy();        
        while ($currentMonth <= $endDate) {
            $monthKey = $currentMonth->format('Y-m');           
            $monthlyData[$monthKey]['month'] = $monthKey;
            $monthlyData[$monthKey]['sales'] = 0;
            $monthlyData[$monthKey]['cashreceipt'] = 0;
            foreach($estimateData as $esrow){
                if ($esrow['month'] === $monthKey) {
                    $monthlyData[$monthKey]['sales'] = $esrow['total_amount'];
                    break;
                }
            }
            foreach($cashReceiptData as $cashrow){
                if ($cashrow['month'] === $monthKey) {
                    $monthlyData[$monthKey]['cashreceipt'] = $cashrow['total_amount'];
                    break;
                }
            }            
            $currentMonth->addMonth();
        }

        // Sort the monthly data by month
        ksort($monthlyData);
        return view('admin.customer.view-allmonthly-detail',compact('customer','openingBalance','monthlyData','yearlist','year'));        
    }


    public function viewCustomerMonthDetail(string $uuid,string $month)
    {
        $customer = Customer::where('uuid',$uuid)->firstOrFail();
        
        $year = substr($month, 0, 4);
        $openingBalance = GetMonthWiseOpeningBalance($customer->id,$month);
       
        $estimateData = PaymentTransaction::selectRaw("*,'sales' as type")
        ->where('customer_id', $customer->id)
        ->where('payment_way', 'order_create')
        ->whereRaw("DATE_FORMAT(entry_date, '%Y-%m') = ?", [$month]);

        $cashReceiptData = PaymentTransaction::selectRaw("*, 'cashreceipt' as type")->where('customer_id', $customer->id)->whereIn('payment_way', ['by_cash', 'by_check', 'by_account'])->whereNotNull('voucher_number')->where('remark', '!=', 'Opening balance')->whereRaw("DATE_FORMAT(entry_date, '%Y-%m') = ?", [$month]);
        
        $alldata = collect($estimateData->get())->merge($cashReceiptData->get());        
        $alldata= $alldata->sortBy('created_at');        
        return view('admin.customer.view-month-detail',compact('customer','alldata','month','openingBalance'));
    }

    public function printPaymentHistory(Request $request)
    {       
        $type = $request->actiontype ;
        $customerId = $request->customer_id ;
        $yearmonth = $request->month ;
        ini_set('max_execution_time', 300);
        $from = null;
        $to = null;
        $year = substr($yearmonth, 0, 4);
        $month = substr($yearmonth, 5, 2);
        $from_date = Carbon::create($year,$month, 1)->startOfMonth();
        $to_date = Carbon::create($year, $month, 1)->endOfMonth();
        try{
            $openingBalance = 0;
            if($customerId)
            {
                $customer = Customer::with(['transaction'=>function($query) use($from_date,$to_date){
                        $query->with(['order'])->whereDate('entry_date','>=',date('Y-m-d', strtotime($from_date)))->whereDate('entry_date','<=',date('Y-m-d', strtotime($to_date)));
                }])->where('uuid',$customerId)->first();   
                
                $openingBalance = GetMonthWiseOpeningBalance($customer->id,$yearmonth);
   
                $pdfData['customer']  = $customer;
                $pdfData['from_date'] = $from_date;
                $pdfData['to_date']   = $to_date;
                $pdfData['openingBalance']   = $openingBalance;
                if($type == 'print-product-ledger')
                {
                    $pdfFileName = 'Print_Ledeger_'.$yearmonth.'.pdf';                    
                    return view('admin.exports.pdf.ledger_print',compact('pdfData','customer','from_date','to_date','openingBalance'))->render();

                }else if($type == 'print-statement')
                {                    
                    return view('admin.exports.pdf.statement_print',compact('pdfData','customer','from_date','to_date','openingBalance'))->render();
                }
            }
        }catch(\Exception $e){
            dd($e->getMessage().'-'.$e->getLine());
            return abort(404);
        }
    }
    
}
