<?php

namespace App\Filament\Resources\StickerValidationResource\Pages;

use App\Filament\Resources\StickerValidationResource;
use App\Models\Item;
use App\Models\ItemCharacteristic;
use App\Models\ProductionQuantity;
use App\Models\StickerDetail;
use App\Models\StickerMappingMaster;
use App\Models\StickerStructureDetail;
use App\Models\StickerValidation;
use App\Services\StickerPdfService;
use Filament\Actions;
use Filament\Facades\Filament;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\CreateRecord;

class CreateStickerValidation extends CreateRecord
{
    protected static string $resource = StickerValidationResource::class;

    protected static string $view = 'filament.resources.sticker-validation-resource.create-sticker-validation';

    public $ref_number;

    public $plantId;

    public $workCenter;

    public $serNo;

    public function getFormActions(): array
    {
        return [
            $this->getCancelFormAction(),
        ];
    }

    protected function getRedirectUrl(): string
    {
        return $this->getResource()::getUrl('create');
    }


    public function processProOrder($value)
    {
        $plantId = $this->form->getState()['plant_id'];

        $this->plantId = $plantId;

        $this->ref_number = $value;

        $this->dispatch('refreshEmptySticker', $plantId, $value);

        $this->dispatch('focus-serial-number');
    }

    public function processSno($serNo)
    {
        $plantId = $this->form->getState()['plant_id'];

        $this->plantId = $plantId;

        $workCenter = $this->form->getState()['machine_id'];

        $this->workCenter = $workCenter;

        $this->ref_number = $this->form->getState()['production_order'];

        $this->serNo = $serNo;

        $user = Filament::auth()->user();

        $operatorName = $user->name;

        if (! preg_match('/^([a-zA-Z0-9]{6,})\|([1-9][a-zA-Z0-9]{8,})\|?$/', $this->serNo, $matches)) {
            Notification::make()
                ->danger()
                ->title('Invalid Serial QR Format')
                ->body('Scan valid Serial QR code proceed!<br>Sample formats are:<br>123456|1234567890123| OR 123456|1234567890123')
                ->seconds(3)
                ->send();

            $this->dispatch('playWarnSound');

            $this->form->fill([
                'plant_id' => $this->plantId,
                'machine_id' => $this->workCenter,
                'production_order' => $this->ref_number,
                'serial_number' => null,
            ]);

            $this->dispatch('focus-serial-number');

            return;
        }
        else {
            $itemCode = $matches[1];
            $serialNumber = $matches[2];

            $recFound = ProductionQuantity::where('plant_id', $this->plantId)
            ->where('production_order', $this->ref_number)
            ->where('serial_number', $serialNumber)
            ->first();

            if(!$recFound){
                Notification::make()
                ->danger()
                ->title('Unknown Serial Number')
                ->body("Scanned serial number '$serialNumber' not found for the given plant and production order")
                ->seconds(3)
                ->send();
                $this->form->fill([
                    'plant_id' => $this->plantId,
                    'machine_id' => $this->workCenter,
                    'production_order' => $this->ref_number,
                    'serial_number' => null,
                ]);
                return;
            }

            $duplicate = StickerValidation::where('plant_id', $this->plantId)
                ->where('production_order', $this->ref_number)
                ->where('serial_number', $serialNumber)
                ->first();

            if ($duplicate) {
                Notification::make()
                    ->danger()
                    ->title('Duplicate Serial Number')
                    ->body("Serial number $serialNumber already exists for this plant and production order!")
                    ->seconds(3)
                    ->send();

                $this->form->fill([
                    'plant_id' => $this->plantId,
                    'machine_id' => $this->workCenter,
                    'production_order' => $this->ref_number,
                    'serial_number' => null,
                ]);
                return;
            }

            $itemC = Item::where('code', $itemCode)
            ->where('plant_id',$this->plantId)
            ->first();

            $itemId = $itemC->id;

            $item = ItemCharacteristic::where('item_id', $itemId)
            ->where('plant_id',$this->plantId)
            ->first();

            $itemI = $item->id;

            $mapping = StickerMappingMaster::where('plant_id', $this->plantId)
                ->where('item_characteristic_id', $itemI)
                ->first();

            if (!$mapping) {
                Notification::make()
                    ->danger()
                    ->title('Sticker Mapping Not Found')
                    ->body("No sticker mapping found for this item and plant.")
                    ->send();
                return;
            }

            $stickers = [];

            for ($i = 1; $i <= 8; $i++) {
                $machineColumn = "sticker{$i}_machine_id";
                $ipColumn      = "sticker{$i}_print_ip";
                $stickerColumn = "sticker_structure{$i}_id";
                $itemColumn = "item_characteristic_id";

                if (
                    !empty($mapping->$machineColumn) &&
                    !empty($mapping->$stickerColumn)
                ) {
                    $stickers[] = [
                        'machine_id' => $mapping->$machineColumn,
                        'sticker_id' => $mapping->$stickerColumn,
                        'item_characteristic'   => $mapping->$itemColumn,
                        'print_ip'   => $mapping->$ipColumn,
                    ];
                }
            }

            if (empty($stickers)) {
                Notification::make()
                    ->danger()
                    ->title('No Sticker Configuration Found')
                    ->body('No sticker and machine mappings configured for this item and plant.')
                    ->send();
                return;
            }

            StickerValidation::create([
                'plant_id' => $this->plantId,
                'machine_id' => $this->workCenter,
                'production_order' => $this->ref_number ?? null,
                'serial_number' => $serialNumber,
                'status'  => 'Printed',
                // 'sticker_id' => $matchedSticker,
                'created_by' => $operatorName,
                'created_at' => now(),
                'updated_at' => now(),
            ]);

            Notification::make()
                ->success()
                ->title('Sticker Recorded')
                ->body("Item: $itemCode, Serial: $serialNumber recorded successfully!")
                ->seconds(3)
                ->send();

            $this->form->fill([
                'plant_id' => $this->plantId,
                'machine_id' => $this->workCenter,
                'production_order' => $this->ref_number,
                'serial_number' => null,
            ]);

            $this->dispatch('refreshEmptySticker', $plantId, $this->ref_number);

            foreach ($stickers as $sticker)
            {

                \Log::info("Looking up printer for IP: " . $sticker['print_ip']);

                $printerName = $this->getCupsPrinterNameByIp($sticker['print_ip']);

                \Log::info("Found printer: " . ($printerName ?? 'NULL'));

                if (! $printerName) {
                    Notification::make()
                        ->danger()
                        ->title('Printer Not Found')
                        ->body("No CUPS printer configured for IP: {$sticker['print_ip']}")
                        ->send();
                    return;
                }

                $structure = StickerStructureDetail::findOrFail($sticker['sticker_id']);

                $itemCharacteristic = ItemCharacteristic::where('plant_id', $this->plantId)
                    ->where('id', $sticker['item_characteristic'])
                    ->firstOrFail();

                $dynamicElements = StickerDetail::where(
                    'sticker_structure_detail_id',
                    $structure->id
                )->where('element_type', 'Dynamic')->get();

                $pdfContent = (new StickerPdfService())->generatePdf1(
                    $structure->sticker_id,
                    $dynamicElements,
                    $itemCharacteristic,
                    $serialNumber,
                    $serNo
                );

                $tempPdfPath = storage_path('app/temp_sticker_' . uniqid() . '.pdf');
                file_put_contents($tempPdfPath, $pdfContent);

                exec(
                    "lp -d " . escapeshellarg($printerName) . " " . escapeshellarg($tempPdfPath),
                    $output,
                    $status
                );

                \Log::info("LP Output:", $output);
                \Log::info("LP Status: " . $status);

                if ($status != 0) {
                    Notification::make()
                        ->danger()
                        ->title('Print Failed')
                        ->body("CUPS error while printing.")
                        ->send();

                    if (file_exists($tempPdfPath)) {
                        unlink($tempPdfPath);
                    }

                    return;
                }

                if (file_exists($tempPdfPath)) {
                    unlink($tempPdfPath);
                }
            }

            Notification::make()
                ->success()
                ->title('Sticker Printed')
                ->body("Sticker for Serial Number: $serialNumber printed successfully!")
                ->seconds(3)
                ->send();

            // [$itemCode, $serialNumber] = explode('|', $serNo);

            // $this->dispatch('open-sticker-pdf', [
            //     'url' => url("/sticker/pdf/{$itemCode}/{$serialNumber}/$this->plantId/$this->ref_number")
            // ]);

        }
    }

    protected function getCupsPrinterNameByIp(string $ip): ?string
    {

        exec('lpstat -v 2>&1', $output, $status); //locak

        // exec('lpstat -h cups:631 -v 2>&1', $output, $status);

        if ($status != 0 || empty($output)) {
            return null;
        }

        foreach ($output as $line){
            $parts = explode(':', $line, 2);
            if (count($parts) < 2) continue;

            $printerName = trim(str_replace('device for', '', $parts[0]));
            $deviceUri = trim($parts[1]);

            if (str_contains($deviceUri, $ip)) {
                return $printerName;
            }
        }
        return null;
    }
}
