<?php
declare (strict_types = 1);

namespace app\admin\controller;

use app\admin\model\v1\LanguageModel;
use app\admin\model\v1\ProductCategoryModel;
use app\admin\model\v1\ProductModel;
use app\admin\model\v1\ProductTcoCategoryModel;
use think\facade\Db;

class Operate_Of_ReceiveSync
{
    const Add     = 'add';
    const Update  = 'update';
    const Enable  = 'enable';
    const Disable = 'disable';
}

/**
 * 接收产品相关同步数据
 */
class ReceiveProductSync
{
    // 接收产品目录分类同步数据
    public function category()
    {
        $data = request()->post();
        if (empty($data)) return error('请确认同步数据');

        $validate = validate([
            'name|分类名称'        => 'require',
            'erp_code|分类ERP编码' => 'require',
        ]);
        if (!$validate->check($data)) {
            return error((string)$validate->getError());
        }

        // 获取对应语言ID
        $lang_id = LanguageModel::where('code', $data['lang'])->value('id');
        if (empty($lang_id)) {
            return error('语言不存在');
        }

        Db::startTrans();
        try {
            $tco_category_data = [
                'language_id'  => $lang_id,
                'name'         => $data['name'],
                'tco_id'       => $data['tco_id'],
                'tco_pid'      => $data['tco_pid'],
                'tco_path'     => $data['tco_path'],
                'erp_id'       => $data['erp_id'],
                'erp_pid'      => $data['erp_pid'],
                'erp_code'     => $data['erp_code'],
                'erp_path'     => $data['erp_path'],
                'disabled'     => Operate_Of_ReceiveSync::Disable == $data['operate'] ? 1 : 0,
                'sync_time'    => strtotime($data['created_at'])
            ];
            $tco_category = ProductTcoCategoryModel::language($lang_id)->erpCode($tco_category_data['erp_code'])->find();
            if (empty($tco_category)) {
                $tco_category = ProductTcoCategoryModel::create($tco_category_data);
                if ($tco_category->isEmpty()) {
                    throw new \Exception('产品目录分类创建失败');
                }

                $category_data = [
                    'language_id'          => $lang_id,
                    'unique_id'            => uniqid('PRO_CATE_'),
                    'pid'                  => 0,
                    'path'                 => '',
                    'name'                 => $tco_category_data['name'],
                    'icon'                 => '',
                    'desc'                 => '',
                    'related_tco_category' => $tco_category['id'],
                    'sort'                 => 0,
                    'level'                => 1,
                    'is_show'              => 1,
                ];
                $tco_parent = ProductTcoCategoryModel::language($lang_id)->tcoId($tco_category['tco_pid'])->find();
                if (!empty($tco_parent)) {
                    $parent = ProductCategoryModel::language($lang_id)->tcoId($tco_parent['id'])->find();
                    if ($parent->isEmpty()) {
                        throw new \Exception('产品分类父级不存在');
                    }
                    $category_data['pid']   = $parent['id'];
                    $category_data['path']  = $parent['path'] . $parent['pid'];
                    $category_data['level'] = $parent['level'] + 1;
                }
                $category = ProductCategoryModel::create($category_data);
                if ($category->isEmpty()) {
                    throw new \Exception('产品分类创建失败');
                }
            }
            else if ($tco_category['sync_time'] < $tco_category_data['sync_time']) {
                $success = $tco_category->save($tco_category_data);
                if (!$success) {
                    throw new \Exception('产品目录分类更新失败');
                }

                $category   = ProductCategoryModel::language($lang_id)->tcoId($tco_category['id'])->find();
                if (!empty($category)) {
                    $tco_parent = ProductTcoCategoryModel::language($lang_id)->tcoId($tco_category['tco_pid'])->find();
                    if (!empty($tco_parent)) {
                        $parent = ProductCategoryModel::language($lang_id)->tcoId($tco_parent['id'])->find();
                        if ($parent->isEmpty()) {
                            throw new \Exception('产品分类父级不存在');
                        }
                        $category['pid']   = $parent['id'];
                        $category['path']  = $parent['path'] . $parent['pid'];
                        $category['level'] = $parent['level'] + 1;
                    }
                    if (!$category->save()) {
                        throw new \Exception('产品分类更新失败');
                    }
                }
            }

            Db::commit();
        } catch (\Throwable $th) {
            Db::rollback();
            return error(sprintf('%s %s:%d', $th->getMessage(), $th->getFile(), $th->getLine()));
        }

        return success('同步成功');
    }

    // 接收产品同步数据
    public function product()
    {
        $data = request()->post();
        if (empty($data)) {
            return error('请确认同步数据');
        }

        $validate = validate([
            'spu'               => 'require',
            'name'              => 'require',
            'category_erp_code' => 'require',
            'lang'              => 'require',
            'created_at'        => 'require',
        ]);
        if (!$validate->check($data)) {
            return error((string)$validate->getError());
        }

        // 获取对应语言ID
        $lang_id = LanguageModel::where('code', $data['lang'])->value('id');
        if (empty($lang_id)) {
            return error('语言不存在');
        }

        // 如果 spu_before_modification 存在则根据 spu_before_modification 更新型号
        $product = null;
        if (!empty($data['spu_before_modification'])) {
            $product = ProductModel::language($lang_id)->spu($data['spu_before_modification'])->find();
        }
        if (
            (empty($data['spu_before_modification']) && !empty($data['spu']))
            // 避免 spu_before_modification 更新型号时，人为删除了旧型号导致的新增，从而出现重复型号问题，而进行再次验证
            || (!empty($data['spu_before_modification']) && empty($product))
        ) {
            $product = ProductModel::language($lang_id)->spu($data['spu'])->find();
        }

        try {
            $product_tco_category = ProductTcoCategoryModel::language($lang_id)->erpCode($data['category_erp_code'])->find();
            if (empty($product_tco_category)) {
                throw new \Exception('官网未找到产品目录同步分类');
            }

            $product_category = ProductCategoryModel::language($lang_id)->tcoId($product_tco_category['id'])->find();
            if (empty($product_category)) {
                throw new \Exception('官网未找到产品目录同步分类关联的分类');
            }

            if (empty($product)) {
                $product = ProductModel::create([
                    'language_id'  => $lang_id,
                    'category_id'  => $product_category['id'],
                    'spu'          => $data['spu'],
                    'name'         => $data['name'],
                    'short_name'   => '',
                    'cover_image'  => '',
                    'desc'         => '',
                    'video_img'    => '',
                    'video_url'    => '',
                    'is_sale'      => 1,
                    'is_new'       => 0,
                    'is_hot'       => 0,
                    'is_show'      => 0,
                    'sort'         => 0,
                    'detail'       => '',
                    'status'       => Operate_Of_ReceiveSync::Disable == $data['operate'] ? -1 : 1,
                    'seo_title'    => '',
                    'seo_keywords' => '',
                    'seo_desc'     => '',
                    'updated_at'   => $data['created_at'],
                ]);
                if ($product->isEmpty()) {
                    throw new \Exception('产品创建失败');
                }
            }
            // 注释更新同步，防止tco同步修改官网手动调整数据
            // else if (strtotime($product['updated_at']) < strtotime($data['created_at'])) {
            //     $product->spu         = $data['spu'];
            //     $product->name        = $data['name'];
            //     $product->category_id = $product_category['id'];
            //     $product->status      = Operate_Of_ReceiveSync::Disable == $data['operate'] ? -1 : 1;
            //     if (!$product->save()) {
            //         throw new \Exception('产品更新失败');
            //     }
            // }
        } catch (\Throwable $th) {
            return error(sprintf('%s %s:%d', $th->getMessage(), $th->getFile(), $th->getLine()));
        }

        return success('同步成功');
    }
}
