<?php

namespace App\Modules\Company\Loan\Billings;

use App\Events\Company\InvoiceUpdateEvent;
use App\Events\Company\LoanBillingNotificationEvent;
use App\Models\InboundBillingRequests;
use App\Models\LoanBorrowList;
use App\Models\ProjectWorkersTimesheet;
use App\Traits\CreateUserActionTraits;
use Illuminate\Support\Facades\DB;
use App\Traits\CreateRealTimeCompanyNotificationTraits;

class UpdateInvoice
{
    use CreateUserActionTraits, CreateRealTimeCompanyNotificationTraits;

    public function updateInvoiceDetailsData($payload, $id)
    {
        $otherExpense = $payload->other_expense;
        $notes = $payload->notes;

        $formData = array(
            'other_expense' => $otherExpense,
            'notes' => $notes,
        );
        InboundBillingRequests::where('loan_borrow_lists_id', $id)->update($formData);

        $data = LoanBorrowList::select('invoice_no')->where('id', $id)->first();

        // Added user transaction for reports
        $this->createUserAction("Updated the billing of invoice " . $data->invoice_no);

        return response()->json(['success' => 'Data updated successfully.'])->setStatusCode(201);
    }

    public function updateInvoiceDaysData($payload, $id)
    {
        // Start transaction
        DB::beginTransaction();

        $days = $payload->days;
        $workerId = $payload->worker_id;
        $workerTimeSheetTransaction = $this->updateWorkerTimeSheet($days, $workerId);
        $formData = array(
            'days' => $days,
        );
        $inboundBillingRequestTransaction = InboundBillingRequests::where('loan_borrow_lists_id', $id)->update($formData);

        $companyNotification = array(
            'type' => 'Borrow Invoice',
            'company_id' => $payload->borrowing_company,
            'link' => '/company/borrow/billing-summary',
            'message' => 'The loaning company updated the invoice for Employee <b>'. $payload->worker_name . '.</b>',
        );
        $this->createCompanyNotification($companyNotification);

        // If there's an error or queries don't do their job, rollback!
        if (!$workerTimeSheetTransaction || !$inboundBillingRequestTransaction) {
            DB::rollBack();
            return response()->json(['error' => 'Server error.']);
        } else {
            DB::commit();
            return response()->json(['success' => 'Data updated successfully.'])->setStatusCode(201);
        }
    }

    public function updateWorkerTimeSheet($days, $workerId)
    {
        foreach ($days as $day) {
            $date = $day['date'];
            $hoursRendered = $day['hours'];
            $formData = array(
                'total_hours' => $hoursRendered,
            );
            ProjectWorkersTimesheet::where('worker_id', $workerId)->where('date', $date)->update($formData);
        }
        return true;
    }

    public function updateInvoiceStatus($payload, $id)
    {
        $status = $payload->status;
        $formData = array(
            'status' => $status,
        );

        $loanBorrowListData = tap(LoanBorrowList::where('id', $id))->update($formData)->first();

        // Added user transaction for reports
        $this->createUserAction("Sent the invoice " . $loanBorrowListData->invoice_no . " to Company Borrower for Approval");

        event(new InvoiceUpdateEvent($loanBorrowListData->id, "invoice", "create"));

        return response()->json(['success' => 'Data updated successfully.'])->setStatusCode(201);
    }

    public function resolveInvoice($payload, $id)
    {
        $otherExpense = $payload->other_expense;
        $notes = $payload->notes;
        $status = 'For Approval';

        // Start Transaction
        DB::beginTransaction();

        //fetch data
        $billingData = $this->fetchLoanBorrowData($id);

        // update inbound_billing_requests table
        $formData = array(
            'other_expense' => $otherExpense,
            'notes' => $notes,
        );
        $inboundBillingRequestTransaction = InboundBillingRequests::where('loan_borrow_lists_id', $id)->update($formData);

        // update loan_borrow_lists table
        $formData = array(
            'status' => $status,
        );
        $loanBorrowListTransaction = LoanBorrowList::where('id', $id)->update($formData);

        // Added user transaction for reports
        $actionTransaction = $this->createUserAction("Resolved a request modification for invoice " . $billingData->invoice_no);

        //notify the borrower company
        $notificationData = (object) [
            'purpose' => 'resolve-modification',
            'company_id' => $billingData->borrower_company_id,
            'full_name' => $billingData->full_name,
            'company_worker_id' => $billingData->company_worker_id,
        ];
        event(new LoanBillingNotificationEvent($notificationData));

        // If there's an error or queries don't do their job, rollback!
        if (!$inboundBillingRequestTransaction || !$loanBorrowListTransaction || !$actionTransaction) {
            DB::rollBack();
            return response()->json(['error' => 'Server error.']);
        } else {
            DB::commit();
            return response()->json(['success' => 'Data updated successfully.'])->setStatusCode(201);
        }
    }

    public function fetchLoanBorrowData($loanBorrowID){
        return LoanBorrowList::select(
                'loan_borrow_lists.*',
                DB::raw('CONCAT(workers.first_name, " ", workers.last_name) as full_name'),
                'workers.worker_id as company_worker_id'
            )
            ->join('workers', 'workers.id', 'loan_borrow_lists.worker_id')
            ->where('loan_borrow_lists.id', $loanBorrowID)
            ->first();
    }
}
