<?php

namespace App\Filament\Imports;

use App\Models\Block;
use App\Models\Line;
use App\Models\Plant;
use App\Models\ProductionPlan;
use App\Models\Shift;
use App\Models\User;
use Carbon\Carbon;
use Filament\Actions\Imports\Exceptions\RowImportFailedException;
use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import;
use Filament\Facades\Filament;
use Str;

class ProductionPlanImporter extends Importer
{
    protected static ?string $model = ProductionPlan::class;

    public static function getColumns(): array
    {
        return [
            ImportColumn::make('created_at')
                ->requiredMapping()
                ->exampleHeader('Created DateTime')
                ->example(['01-01-2025 08:00:00', '01-01-2025 19:30:00'])
                ->label('Created DateTime')
                ->rules(['required']),
            ImportColumn::make('plan_quantity')
                ->requiredMapping()
                ->exampleHeader('Plan Quantity')
                ->example(['500', '450'])
                ->label('Plan Quantity')
                ->numeric()
                ->rules(['required', 'integer']),
            ImportColumn::make('production_quantity')
                ->requiredMapping()
                ->exampleHeader('Production Quantity')
                ->example(['0', '0'])
                ->label('Production Quantity')
                ->numeric()
                ->rules(['required', 'integer']),
            ImportColumn::make('line')
                ->requiredMapping()
                ->exampleHeader('Line Name')
                ->example(['4 inch pump line', '4 inch pump line'])
                ->label('Line Name')
                ->relationship(resolveUsing:'name')
                ->rules(['required']),
            ImportColumn::make('block_reference')
                ->requiredMapping() // Or optionalMapping() if not always present
                ->exampleHeader('Block Name')
                ->example(['Block A', 'Block A'])
                ->label('Block Name')
                ->rules(['required']), // Or remove if not required
            ImportColumn::make('shift')
                ->requiredMapping()
                ->exampleHeader('Shift Name') //ID
                ->example(['Day', 'Night']) //'2', '7'
                ->label('Shift Name') // ID
                ->relationship(resolveUsing: 'name')
                ->rules(['required']),
            ImportColumn::make('plant')
                ->requiredMapping()
                ->exampleHeader('Plant Name')
                ->example(['Ransar Industries-I', 'Ransar Industries-I'])
                ->label('Plant Name')
                ->relationship(resolveUsing:'name')
                ->rules(['required']),
            ImportColumn::make('updated_at')
                ->requiredMapping()
                ->exampleHeader('Updated DateTime')
                ->example(['01-01-2025 08:00:00', '01-01-2025 19:30:00'])
                ->label('Updated DateTime')
                ->rules(['required']),
            ImportColumn::make('operator_id')
                ->requiredMapping()
                ->exampleHeader('Operator ID')
                ->example([Filament::auth()->user()->name, Filament::auth()->user()->name])
                ->label('Operator ID')
                ->rules(['required']),
        ];
    }

    public function resolveRecord(): ?ProductionPlan
    {
        $warnMsg = [];
        $plant = Plant::where('name', $this->data['plant'])->first();
        $line = null;
        $block = null;
        if (!$plant) {
            $warnMsg[] = "Plant not found";
        }
        else {
            $line = Line::where('name', $this->data['line'])->where('plant_id', $plant->id)->first();
            //block_reference
            $block = Block::where('name', $this->data['block_reference'])->where('plant_id', $plant->id)->first();
        }
        if (!$line) {
            $warnMsg[] = "Line not found";
        }
        $shift = null;
        if (!$block) {
            $warnMsg[] = "Block not found";
        }
        else {
            $shift = Shift::where('name', $this->data['shift'])->where('plant_id', $plant->id)->where('block_id', $block->id)->first();
        }
        //$shift = Shift::where('id', $this->data['shift'])->where('plant_id', $plant->id)->first();
        if (!$shift) {
            $warnMsg[] = "Shift not found";
        }
        if (Str::length($this->data['plan_quantity']) < 0 || !is_numeric($this->data['plan_quantity']) || $this->data['plan_quantity'] <= 0) {
            $warnMsg[] = "Invalid plan quantity found";
        }
        if (Str::length($this->data['production_quantity']) < 0 || !is_numeric($this->data['production_quantity']) || $this->data['production_quantity'] < 0) {
            $warnMsg[] = "Invalid production quantity found";
        }

        $fromDate = $this->data['created_at'];
        $toDate = $this->data['updated_at'];

        $formats = ['d-m-Y H:i', 'd-m-Y H:i:s']; //'07-05-2025 08:00' or '07-05-2025 08:00:00'

        $fdateTime = null;
        $tdateTime = null;
        // Try parsing with multiple formats
        foreach ($formats as $format) {
            try {
                $fdateTime = Carbon::createFromFormat($format, $fromDate);
                break;
            } catch (\Exception $e) {
                // Optionally collect warning messages
                // $warnMsg[] = "Date format mismatch with format: $format";
            }
        }

        foreach ($formats as $format) {
            try {
                $tdateTime = Carbon::createFromFormat($format, $toDate);
                break;
            } catch (\Exception $e) {
                // Optionally collect warning messages
                // $warnMsg[] = "Date format mismatch with format: $format";
            }
        }

        $fDateOnly = '';
        if (!isset($fdateTime)) {
            // throw new \Exception('Invalid date time format');
            $warnMsg[] = "Invalid 'Created DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
        }
        else {
            $fDateOnly = $fdateTime->toDateString();
        }
        if (!isset($tdateTime)) {
            $warnMsg[] = "Invalid 'Updated DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
        }

        if (isset($fdateTime) && isset($tdateTime)) {
            if ($fdateTime->greaterThan($tdateTime)) {
                $warnMsg[] = "'Created DataTime' is greater than 'Updated DateTime'.";
            }
        }

        // if (!$fromDate) {
        //     $warnMsg[] = "Invalid 'Created DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
        // }
        // else if (!$toDate) {
        //     $warnMsg[] = "Invalid 'Updated DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
        // }

        $user = User::where('name', $this->data['operator_id'])->first();
        if (!$user) {
            $warnMsg[] = "Operator ID not found";
        }

        if (!empty($warnMsg)) {
            throw new RowImportFailedException(implode(', ', $warnMsg));
        }
        else { //if (empty($warnMsg))
            $productionPlan = ProductionPlan::where('plant_id', $plant->id)
            ->where('shift_id', $shift->id)
            ->where('line_id', $line->id)
            ->whereDate('created_at', $fDateOnly)
            // ->where('plan_quantity', $productionQuantity->plan_quantity)
            ->latest()
            ->first();

            if ($productionPlan) {
                // if($productionPlan->production_quantity)
                // {
                //     throw new RowImportFailedException("{$productionPlan->created_at}, {$productionPlan->production_quantity}");
                // }
                // $warnMsg[] = "Production plan already exist on '{$fDateOnly}'!";

                $productionPlan->update([
                    'plan_quantity' => $this->data['plan_quantity'],
                    // 'production_quantity' => $productionPlan->production_quantity,
                    // 'created_at' => $productionPlan->created_at,//$fdateTime->format('Y-m-d H:i:s'),
                    // 'updated_at' => $tdateTime->format('Y-m-d H:i:s'),
                    'operator_id' => $this->data['operator_id'],
                ]);
                $productionPlan->save();
                return null;
            }
        }

        ProductionPlan::updateOrCreate([
            'plant_id' => $plant->id,
            'line_id' => $line->id,
            'shift_id' => $shift->id,
            'plan_quantity' => $this->data['plan_quantity'],
            'production_quantity' => $this->data['production_quantity'],
            'created_at' => $fdateTime->format('Y-m-d H:i:s'),//$this->data['created_at'],
            'updated_at' => $tdateTime->format('Y-m-d H:i:s'),//$this->data['updated_at'],
            'operator_id' => $this->data['operator_id'],
        ]);
        return null;
        // return ProductionPlan::firstOrNew([
        //     // Update existing records, matching them by `$this->data['column_name']`
        //     'email' => $this->data['email'],
        // ]);

        // return new ProductionPlan();
    }

    public static function getCompletedNotificationBody(Import $import): string
    {
        $body = 'Your production plan import has completed and ' . number_format($import->successful_rows) . ' ' . str('row')->plural($import->successful_rows) . ' imported.';

        if ($failedRowsCount = $import->getFailedRowsCount()) {
            $body .= ' ' . number_format($failedRowsCount) . ' ' . str('row')->plural($failedRowsCount) . ' failed to import.';
        }

        return $body;
    }
}
