<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Invoice;
use App\Models\Client;
use Illuminate\Support\Facades\Http;
use App\Models\Invotek;
use App\Models\Product;
use App\Services\InvotekService;
class InvoiceController extends Controller
{
    public function __construct()
    {
        $this->middleware('permission:invoices-list', ['only' => ['index']]);
        $this->middleware('permission:invoices-create', ['only' => ['create', 'store']]);
        $this->middleware('permission:invoices-edit', ['only' => ['edit', 'update']]);
        $this->middleware('permission:invoices-show', ['only' => ['show']]);
        $this->middleware('permission:invoices-delete', ['only' => ['destroy']]);
        $this->middleware('permission:invoices-resend', ['only' => ['resendInvoice']]);
        }

    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        $invoices = Invoice::with('client')->get();
        return view('admin.invoices.index', compact('invoices'));
    }
    public function returnInvoiceIndex()
    {
        $invoices = Invoice::with('client')->where('sent_to_invotek', 2)->get();
        return view('admin.invoices.return-invoice-index', compact('invoices'));
    }
    public function notResendInvoiceIndex()
    {
        $invoices = Invoice::with('client')->where('sent_to_invotek', 0)->get();
        return view('admin.invoices.not-resend-invoice-index', compact('invoices'));
    }

    /**
     * Show the form for creating a new resource.
     */

     public function create()
     {
         $products = Product::all();
         $clients = Client::all();
         $cities = \App\Models\City::all();
         $countries = \App\Models\Country::all();
         $paymentMethods = [
             '011' => 'Cash',
             '021' => 'Credit'
         ];
         $defaultInvoiceNumber = $this->generateInvoiceNumber(); // Implement this method
         $defaultDate = now()->format('Y-m-d');

         return view('admin.invoices.create', compact('products', 'paymentMethods', 'defaultInvoiceNumber', 'defaultDate', 'clients', 'cities', 'countries'));
     }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        // dd($request->all());
        $request->validate([
            'number' => 'required|unique:invoices',
            'total_price' => 'required',
            'payment_method_code' => 'required',
            'issue_date' => 'required',
            'client_id' => 'required',
            'items' => 'required|array',
            'items.*.name' => 'required',
            'items.*.price' => 'required',
            'items.*.quantity' => 'required',
            'items.*.total' => 'required',
            'items.*.discount' => 'required',
        ]);

        $data = $request->all();
        $data['status'] = 'pending';
        $invoice = Invoice::create($data);

        $invoice->details()->createMany($request->items);
        $invotek = Invotek::first();
        if ($invotek->type == 'income' && $invotek->active == 1) {

            try {
                $invotekService = new InvotekService();
                $response = $invotekService->getIncome($invoice,$invoice->details,$invoice->client);

                if ($response->successful()) {
                    $responseData = $response->json();

                    if (!empty($responseData) && isset($responseData['data']['EINV_QR'])) {
                        $invoice->sent_to_invotek = 1;
                        $invoice->status = 'sending_to_invotek';
                        $invoice->einv_qr = $responseData['data']['EINV_QR'];
                        $invoice->uuid = $responseData['data']['EINV_INV_UUID'];
                        $invoice->save();

                        return redirect()->route('admin.invoices.show', $invoice->id)->with('success', __('translations.invoice_sent_successfully'));
                    } else {
                        return redirect()->route('admin.invoices.show', $invoice->id)->with('error', __('translations.failed_response_empty'));
                    }
                } else {
                    return redirect()->route('admin.invoices.index')->with('error', __('translations.failed to send invoice to invotek', ['error' => $response->body()]));
                }
            } catch (\Exception $e) {
                return redirect()->route('admin.invoices.index')->with('error', __('translations.failed to send invoice to invotek', ['error' => $e->getMessage()]));
            }
        }

        return redirect()->route('admin.invoices.show', $invoice->id);
    }
    public function returnInvoice(Request $request, string $id)
    {
        $invoice = Invoice::find($request->id);
        $invotek = Invotek::first();
        if ($invotek->type == 'income' && $invotek->active == 1 && $invoice->sent_to_invotek == 1) {
        $defaultInvoiceNumber = $this->generateInvoiceNumber(); // Implement this method
        $returnInvoice = Invoice::create([
            'number' => $defaultInvoiceNumber,
            'total_price' => $invoice->total_price,
            'payment_method_code' => $invoice->payment_method_code,
            'issue_date' => now()->format('Y-m-d'),
            'client_id' => $invoice->client_id,
            'status' => 'pending',
            'return_reason' => $request->return_reason,
            'origin_number' => $invoice->number,
            'original_uid' => $invoice->uuid,
        ]);

        $detailsArray = $invoice->details->map(function($detail) {
            $attributes = $detail->toArray();
            // Remove fields that shouldn't be duplicated
            unset($attributes['id']);
            unset($attributes['created_at']);
            unset($attributes['updated_at']);
            return $attributes;
        })->toArray();

        $returnInvoice->details()->createMany($detailsArray);

            try {

                $invotekService = new InvotekService();
                $response = $invotekService->getReturnInvoice($invoice,$invoice->details,$invoice->client,$returnInvoice);
                if ($response->successful()) {
                    $responseData = $response->json();

                    if (!empty($responseData) && isset($responseData['data']['EINV_QR'])) {
                        // return $responseData;
                        $invoice->sent_to_invotek = 2;
                        $invoice->status = 'returned';
                        $invoice->einv_qr = $responseData['data']['EINV_QR'];
                        $invoice->uuid = $responseData['data']['EINV_INV_UUID'];
                        $invoice->save();

                        return redirect()->route('admin.invoices.index')->with('success', __('translations.invoice_returned_successfully'));
                    } else {
                        $returnInvoice->delete();
                        return redirect()->route('admin.invoices.index')->with('error', __('translations.failed_response_empty'));
                    }
                } else {
                    $returnInvoice->delete();
                    return redirect()->route('admin.invoices.index')->with('error', __('translations.failed to return invoice to invotek', ['error' => $response->body()]));
                }
            } catch (\Exception $e) {
                $returnInvoice->delete();
                return redirect()->route('admin.invoices.index')->with('error', __('translations.failed to return invoice to invotek', ['error' => $e->getMessage()]));
            }
            return redirect()->route('admin.invoices.index');
        }
        return redirect()->route('admin.invoices.index')->with('error', __('translations.not active to return invoice to invotek'));
    }

    public function resendInvoice(Request $request, string $id)
    {
        $invotek = Invotek::first();
        $invoice = Invoice::with('details','client')->find($id);
        $invotekService = new InvotekService();
        if ($invotek->type == 'income' && $invotek->active == 1 && $invoice->sent_to_invotek == 0) {
            try {
                $response = $invotekService->getIncome($invoice,$invoice->details,$invoice->client);
                $responseData = $response->json();
                    if ($response->successful() && !empty($responseData) && isset($responseData['data']['EINV_QR'])) {
                        $invoice->sent_to_invotek = 1;
                        $invoice->status = 'sending_to_invotek';
                        $invoice->einv_qr = $responseData['data']['EINV_QR'];
                        $invoice->uuid = $responseData['data']['EINV_INV_UUID'];
                        $invoice->save();
                        return redirect()->route('admin.invoices.index')->with('success', __('translations.invoice_sent_successfully'));
                    } else {
                        return redirect()->route('admin.invoices.index')->with('error', __('translations.failed to send invoice to invotek', ['error' => $response->body()]));
                    }
            } catch (\Exception $e) {
                return redirect()->route('admin.invoices.index')->with('error', __('translations.failed to send invoice to invotek', ['error' => $e->getMessage()]));
            }
        }
        return redirect()->route('admin.invoices.show', $invoice->id)->with('error', __('translations.not active to send invoice to invotek'));
    }
    /**
     * Display the specified resource.
     */
    public function show(string $id)
    {
        $invoice = Invoice::find($id);
        return view('admin.invoices.show', compact('invoice'));
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(string $id)
    {
        $invoice = Invoice::find($id);
        $clients = Client::all();
        $products = Product::all();
        $paymentMethods = [
            '011' => 'Cash',
            '021' => 'Credit'
        ];

        return view('admin.invoices.edit', compact('invoice', 'clients', 'products', 'paymentMethods'));
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, string $id)
    {
        $invoice = Invoice::find($id);
        $invoice->update($request->all());
        return redirect()->route('admin.invoices.index');
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(string $id)
    {
        $invoice = Invoice::find($id);
        $invoice->delete();
        return redirect()->route('admin.invoices.index');
    }

    private function generateInvoiceNumber()
    {
        // Get the current date in the format YYYYMMDD
        $date = now()->format('Ymd');

        // Get the last invoice number for today
        $lastInvoice = Invoice::where('number', 'like', $date . '%')->orderBy('number', 'desc')->first();

        if ($lastInvoice) {
            // Extract the sequential number from the last invoice number
            $lastNumber = (int)substr($lastInvoice->number, 8);
            // Increment the number
            $newNumber = $lastNumber + 1;
        } else {
            // Start with 1 if no invoices exist for today
            $newNumber = 1;
        }

        // Format the new invoice number with leading zeros
        $formattedNumber = str_pad($newNumber, 4, '0', STR_PAD_LEFT);

        // Combine the date and the new number
        return $date . $formattedNumber;
    }
}
