<?php

declare(strict_types=1);

namespace App\Services;

use App\Models\HealthTreatment;
use App\Models\Product;
use App\Models\Report;

class HealthTreatmentSyncService
{
    public function syncFromApprovedReport(Report $report): void
    {
        if (! $report->isHealthReport() || $report->workflow_status !== Report::WORKFLOW_APPROVED) {
            return;
        }

        $report->loadMissing(['items.product.breed', 'producer']);

        if ($report->report_type === Report::HEALTH_TYPE_REMOVE_PRODUCT) {
            $this->markRemoved($report);

            return;
        }

        if (! in_array($report->report_type, [
            Report::HEALTH_TYPE_TREATMENT,
            Report::HEALTH_TYPE_DEHORNING,
            Report::HEALTH_TYPE_VACCINATION,
            Report::HEALTH_TYPE_OTHER,
        ], true)) {
            return;
        }

        // Vaccination alone does not open an under-treatment case unless disease/treatment context exists.
        if ($report->report_type === Report::HEALTH_TYPE_VACCINATION && blank($report->disease_name)) {
            return;
        }

        $productIds = $report->items->pluck('product_id')->filter()->unique()->values();
        if ($productIds->isEmpty() && $report->product_id) {
            $productIds = collect([$report->product_id]);
        }

        foreach ($productIds as $productId) {
            /** @var Product|null $product */
            $product = $report->items->firstWhere('product_id', $productId)?->product
                ?? Product::with('breed')->find($productId);

            $existing = HealthTreatment::query()
                ->where('project_id', $report->project_id)
                ->where('product_id', $productId)
                ->whereIn('status', [
                    HealthTreatment::STATUS_UNDER_TREATMENT,
                    HealthTreatment::STATUS_UNDER_OBSERVATION,
                ])
                ->first();

            $payload = [
                'producer_id' => $report->producer_id,
                'initial_report_id' => $report->id,
                'product_code' => $product?->code,
                'product_name' => $product?->name,
                'breed_name' => $product?->breed?->name,
                'disease_name' => $report->disease_name,
                'weight' => $report->product_weight,
                'next_visit_at' => $report->next_visit_at,
                'attachments' => $report->attachments,
                'notes' => $report->diagnosis,
                'updated_by' => $report->updated_by,
            ];

            if ($existing) {
                $existing->update($payload);

                continue;
            }

            HealthTreatment::create(array_merge($payload, [
                'project_id' => $report->project_id,
                'product_id' => $productId,
                'status' => HealthTreatment::STATUS_UNDER_TREATMENT,
                'progress_percent' => 0,
                'started_at' => $report->report_at ?? $report->date ?? now(),
                'created_by' => $report->created_by,
            ]));
        }
    }

    private function markRemoved(Report $report): void
    {
        $productIds = $report->items->pluck('product_id')->filter()->unique()->values();
        if ($productIds->isEmpty() && $report->product_id) {
            $productIds = collect([$report->product_id]);
        }

        HealthTreatment::query()
            ->where('project_id', $report->project_id)
            ->whereIn('product_id', $productIds)
            ->whereIn('status', [
                HealthTreatment::STATUS_UNDER_TREATMENT,
                HealthTreatment::STATUS_UNDER_OBSERVATION,
            ])
            ->update([
                'status' => HealthTreatment::STATUS_REMOVED,
                'ended_at' => $report->report_at ?? now(),
                'weight' => $report->product_weight,
                'updated_by' => $report->updated_by,
            ]);

        foreach ($productIds as $productId) {
            $exists = HealthTreatment::query()
                ->where('project_id', $report->project_id)
                ->where('product_id', $productId)
                ->exists();

            if ($exists) {
                continue;
            }

            $product = Product::with('breed')->find($productId);
            HealthTreatment::create([
                'project_id' => $report->project_id,
                'product_id' => $productId,
                'producer_id' => $report->producer_id,
                'initial_report_id' => $report->id,
                'product_code' => $product?->code,
                'product_name' => $product?->name,
                'breed_name' => $product?->breed?->name,
                'disease_name' => $report->disease_name,
                'status' => HealthTreatment::STATUS_REMOVED,
                'progress_percent' => 100,
                'weight' => $report->product_weight,
                'started_at' => $report->report_at ?? now(),
                'ended_at' => $report->report_at ?? now(),
                'attachments' => $report->attachments,
                'notes' => $report->diagnosis,
                'created_by' => $report->created_by,
                'updated_by' => $report->updated_by,
            ]);
        }
    }
}
