<?php

namespace App\Services;

use App\Models\Company;
use App\Models\GrnItemBatch;
use App\Models\RawMaterialItem;
use App\Models\StoreIssueRequisition;
use App\Models\StoreIssueRequisitionItem;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

class StoreIssueRequisitionService
{
    public function getAll()
    {
        $requisitions = StoreIssueRequisition::with(['chart_of_account', 'product_variation', 'batch', 'company'])->orderBy('created_at', 'asc')->get();
        return $requisitions;
    }

    public function create(array $data)
    {
        // dd($data);
        return DB::transaction(function () use($data) {
            $items = $data['items'] ?? [];

            $data['chart_of_account_id'] = $data['chart_of_account'] ?? null;
            $data['product_variation_id'] = $data['product_variation'] ?? null;
            $data['batch_id'] = $data['batch'] ?? null;
            $data['company_id'] = $data['company'];

            $requisition = StoreIssueRequisition::create($data);

            foreach ($items as $item) {
                if (isset($item['product'])) {
                    if (str_starts_with($item['product'], 'product_')) {
                        $item['product_id'] = str_replace('product_', '', $item['product']);
                        $item['raw_material_item_id'] = null;
                        $item['product_variation_id'] = null;
                    } elseif (str_starts_with($item['product'], 'raw_')) {
                        $item['raw_material_item_id'] = str_replace('raw_', '', $item['product']);
                        $item['product_id'] = null;
                        $item['product_variation_id'] = null;
                    } elseif (str_starts_with($item['product'], 'var_')) {
                        $item['product_variation_id'] = str_replace('var_', '', $item['product']);
                        $item['raw_material_item_id'] = null;
                        $item['product_id'] = null;
                    }
                } elseif (isset($item['raw_material_item'])) {
                    $item['raw_material_item_id'] = $item['raw_material_item'] ?? null;
                }
                $item['batch_id'] = $item['batch'] ?? null;
                $item['stock'] = $item['stock'] ?? null;

                $requisition->items()->create($item);
                $item['company_id'] = $data['company_id'];
                $requisition->stocks()->create($item);

                if ($requisition->is_production == '1') {
                    $batch = GrnItemBatch::find($item['batch_id']);
                    $batch->update([
                        'sir_issued_qty' => $batch->sir_issued_qty + $item['quantity'],
                    ]);
                }
            }

            return $requisition;
        });
    }

    public function update(StoreIssueRequisition $storeIssueRequisition, array $data)
    {
        return DB::transaction(function () use ($storeIssueRequisition, $data) {
            $items = $data['items'] ?? [];

            $data['chart_of_account_id'] = $data['chart_of_account'] ?? null;
            $data['product_variation_id'] = $data['product_variation'] ?? null;
            $data['batch_id'] = $data['batch'] ?? null;
            $data['company_id'] = $data['company'];

            $storeIssueRequisition->update($data);

            foreach ($storeIssueRequisition->items as $sirItem) {
                $oldQty = $sirItem->quantity;
                // dd($oldQty, isset($sirItem->raw_material_item_id) && isset($sirItem->batch_id) && get_class($sirItem->batch) == 'App\Models\GrnItemBatch');
                if (isset($sirItem->raw_material_item_id) && isset($sirItem->batch_id) && get_class($sirItem->batch) == 'App\Models\GrnItemBatch') {
                    GrnItemBatch::find($sirItem->batch_id)->update([
                        'sir_issued_qty' => $sirItem->batch->sir_issued_qty - $oldQty
                    ]);
                }
                // $sirItem->delete();
            }
            $storeIssueRequisition->items()->delete();
            $item['company_id'] = $data['company_id'];
            $storeIssueRequisition->stocks()->delete();

            foreach ($items as $item) {
                if (isset($item['product'])) {
                    if (str_starts_with($item['product'], 'product_')) {
                        $item['product_id'] = str_replace('product_', '', $item['product']);
                        $item['raw_material_item_id'] = null;
                        $item['product_variation_id'] = null;
                    } elseif (str_starts_with($item['product'], 'raw_')) {
                        $item['raw_material_item_id'] = str_replace('raw_', '', $item['product']);
                        $item['product_id'] = null;
                        $item['product_variation_id'] = null;
                    } elseif (str_starts_with($item['product'], 'var_')) {
                        $item['product_variation_id'] = str_replace('var_', '', $item['product']);
                        $item['raw_material_item_id'] = null;
                        $item['product_id'] = null;
                    }
                } elseif (isset($item['raw_material_item'])) {
                    $item['raw_material_item_id'] = $item['raw_material_item'] ?? null;
                }
                $item['batch_id'] = $item['batch'] ?? null;
                // dump($item);
                // $item['stock'] = $item['stock'] ?? null;
                // dd($item);
                
                $storeIssueRequisition->items()->create($item);
                $item['company_id'] = $data['company_id'];
                $storeIssueRequisition->stocks()->create($item);

                if ($storeIssueRequisition->is_production == '1') {
                    $batch = GrnItemBatch::find($item['batch']);
                    $batch->update([
                        'sir_issued_qty' => $batch->sir_issued_qty + $item['quantity'],
                    ]);
                }
            }

            return $storeIssueRequisition;
        });
    }

    public function delete(StoreIssueRequisition $storeIssueRequisition)
    {
        $storeIssueRequisition->stocks()->delete();
        return $storeIssueRequisition->delete();
    }

    public function getById($id)
    {
        return StoreIssueRequisition::findOrFail($id);
    }

    public function createCode($company_id)
    {
        $lastRequisitionCode = StoreIssueRequisition::latest('id')->where('company_id', $company_id)->value('code');
        if ($lastRequisitionCode) {
            $numberPart = (int) substr($lastRequisitionCode, 3);
            $newNumberPart = $numberPart + 1;
            $newRequisitionCode = 'SIR' . str_pad($newNumberPart, 5, '0', STR_PAD_LEFT);
        } else {
            $newRequisitionCode = 'SIR00001';
        }
        return $newRequisitionCode;
    }

    public function getConsumptionReport($from_date, $to_date)
    {
        $storeIssueRequisition = StoreIssueRequisitionItem::select(
            'raw_material_item_id',
            'raw_material_items.name',
            'raw_material_items.code',
            'raw_material_items.unit',
            DB::raw('SUM(quantity) as total_quantity'),
            DB::raw('AVG(unit_price) as average_unit_price')
        )
            ->whereNotNull('raw_material_item_id')
            ->whereHas('store_issue_requisition', function ($query) use ($from_date, $to_date) {
                $query->where('is_production', 1)->whereBetween('created_at', [$from_date, $to_date]);
            })
            ->join('raw_material_items', 'store_issue_requisition_items.raw_material_item_id', '=', 'raw_material_items.id')
            ->groupBy('raw_material_item_id', 'raw_material_items.name', 'raw_material_items.code', 'raw_material_items.unit')
            ->get();

        return $storeIssueRequisition;
    }
}
