<?php

namespace App\Console\Commands\Utils;

use App\Models\Backoffice\WebsiteObject;
use App\Models\Backoffice\WebsiteObjectLanguage;
use App\Models\Cpv;
use App\Models\CpvLanguage;
use App\Models\Department;
use App\Models\DepartmentLanguage;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
use Throwable;

class ImportCpvs extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'utils:import-cpvs';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Import cpvs to a JSON file';

    /**
     * Execute the console command.
     */
    public function handle()
    {
        $jsonFolderPath = base_path('json');

        $cpvsFilePath = $jsonFolderPath . '/cpvs-out.json';
        $departmentsFilePath = $jsonFolderPath . '/departments-out.json';
        if (!File::exists($cpvsFilePath)) {
            $this->error('CPVs JSON file not found: ' . $cpvsFilePath);
            return;
        }
        if (!File::exists($departmentsFilePath)) {
            $this->error('Departments JSON file not found: ' . $departmentsFilePath);
            return;
        }

        // Import CPVs
        $cpvsData = json_decode(File::get($cpvsFilePath), true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            $this->error('Invalid JSON format in file: ' . $cpvsFilePath);
            return;
        }

        // Import Departments
        $departmentsData = json_decode(File::get($departmentsFilePath), true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            $this->error('Invalid JSON format in file: ' . $departmentsFilePath);
            return;
        }

        $languages = LaravelLocalization::getSupportedLanguagesKeys();

        DB::beginTransaction();
        try {
            foreach ($cpvsData as $data) {
                if (strlen($data['cpvCode']) < 3) {
                    // these will be our departments
                    continue;
                }

                if ($data['oo_id'] && Cpv::where('migration_object_id', $data['oo_id'])->exists()) {
                    $this->warn('CPV with migration object ID ' . $data['oo_id'] . ' already exists. Skipping.');
                    continue;
                }

                if ($data['cpvCode'] && Cpv::where('full_code', $data['cpvCode'])->exists()) {
                    $this->warn('CPV with code ' . $data['cpvCode'] . ' already exists. Skipping.');
                    continue;
                }

                $cpv = new Cpv();
                $cpv->full_code = $data['cpvCode'];
                $cpv->code = mb_substr($data['cpvCode'], 0, 8);
                if ($cpv->code == '00000000') {
                    $cpv->code = null;
                }
                $cpv->migration_object_id = $data['oo_id'];
                $cpv->save();

                $wo = new WebsiteObject();
                $wo->object_id = $cpv->id;
                $wo->object_type = Cpv::class;
                $wo->content_type = 'cpv';
                $wo->save();

                foreach ($languages as $lang) {
                    $cpvLanguage = new CpvLanguage();
                    $cpvLanguage->cpv_id = $cpv->id;
                    $cpvLanguage->language_id = $lang;
                    $cpvLanguage->title = $data['cpvDescription'];
                    $cpvLanguage->save();

                    $wol = new WebsiteObjectLanguage();
                    $wol->website_object_id = $wo->id;
                    $wol->wo_language_id = $lang;
                    $wol->save();
                }
            }

            $departmentsData = json_decode(File::get($departmentsFilePath), true);

            $departmentIdMap = [];
            foreach ($departmentsData as $data) {
                if ($data['code'] && Department::where('code', $data['code'])->exists()) {
                    $departmentIdMap[$data['export_id']] = Department::where('code', $data['code'])->first()->id;
                    $this->warn('Department with code ' . $data['code'] . ' already exists. Skipping.');
                    continue;
                }

                $department = new Department();
                $department->code = $data['code'];
                $department->save();
                $departmentIdMap[$data['export_id']] = $department->id;

                Cpv::whereIn('full_code', $data['cpvs'])->each(function ($cpv) use ($department) {
                    $department->cpvs()->attach($cpv->id);
                });

                $wo = new WebsiteObject();
                $wo->object_id = $department->id;
                $wo->object_type = Department::class;
                $wo->content_type = 'department';

                $wo->save();

                foreach ($languages as $lang) {
                    $departmentLanguage = new DepartmentLanguage();
                    $departmentLanguage->department_id = $department->id;
                    $departmentLanguage->language_id = $lang;
                    $departmentLanguage->title = $data['title'];
                    $departmentLanguage->save();

                    $wol = new WebsiteObjectLanguage();
                    $wol->website_object_id = $wo->id;
                    $wol->wo_language_id = $lang;
                    $wol->save();
                }
            }

            // structure departments
            foreach ($departmentsData as $data) {
                if (empty($data['export_parent_id'])) {
                    continue; // No parent, skip
                }

                $parentDepartment = Department::find($departmentIdMap[$data['export_parent_id']] ?? null);
                if (!$parentDepartment) {
                    $this->warn('Parent department with export ID ' . $data['export_parent_id'] . ' not found. Skipping.');
                    continue;
                }

                $department = Department::find($departmentIdMap[$data['export_id']] ?? null);
                if ($department) {
                    $wo = $department->websites->first();
                    $wo->parent_id = $parentDepartment->website_object_id;
                    $wo->save();
                }
            }

            DB::commit();
        } catch (Throwable $e) {
            DB::rollBack();
            throw($e);
        }
    }
}
