<?php

declare(strict_types=1);

namespace app\admin\controller\v1;

use app\admin\model\v1\ProductModel;
use app\admin\model\v1\ProductPurchaseLinkModel;
use app\admin\model\v1\ProductPurchaseLinkPlatformModel;
use app\admin\validate\v1\ProductPurchaseLinkValidate;
use think\facade\Db;

class ProductPurchaseLink
{
    /**
     * 获取购买平台
     */
    public function platforms()
    {
        $platforms = ProductPurchaseLinkPlatformModel::withoutField([
                'language_id',
                'desc',
                'sort',
                'created_at'
            ])
            ->language(request()->lang_id)
            ->order(['sort' => 'asc', 'id' => 'desc'])
            ->select();

        return success('获取成功', $platforms);
    }

    /**
     * 购买链接分页数据
     */
    public function index()
    {
        $params = request()->param([
            'name'   => '',
            'spu'    => '',
            'page/d' => 1,
            'size/d' => 10
        ]);

        $links = ProductModel::alias('pd')
            ->field([
                'pd.id',
                'IFNULL(pl.sort, 0)' => 'sort',
                'pd.spu',
                'pd.name',
                'pd.is_show'
            ])
            ->leftJoin('product_purchase_link pl', 'pl.product_id = pd.id')
            ->leftJoin('product_purchase_platform pf', 'pf.id = pl.platform_id')
            ->where(function ($query) use ($params) {
                $query->where('pd.is_show', '=', 1);
                if (!empty($params['name'])) {
                    $query->where('pd.name', 'like', '%' . $params['name'] . '%');
                }
                if (!empty($params['spu'])) {
                    $query->where('pd.spu', 'like', '%' . $params['spu'] . '%');
                }
            })
            ->where('pd.language_id', '=', request()->lang_id)
            ->group('pd.id')
            ->order(['sort' => 'asc', 'pd.id' => 'desc'])
            ->hidden(['sort'])
            ->paginate([
                'list_rows' => $params['size'],
                'page'      => $params['page'],
            ]);
        if ($links->isEmpty()) {
            return success('获取成功', []);
        }

        // 获取购买链接数据
        $others = ProductPurchaseLinkModel::alias('pl')
            ->field([
                'pl.product_id',
                'pl.platform_id',
                'pf.platform' => 'platform_name',
                'pl.id'       => 'link_id',
                'pl.link'
            ])
            ->join('product_purchase_platform pf', 'pf.id = pl.platform_id')
            ->where('pl.language_id', '=', request()->lang_id)
            ->where('pl.product_id', 'in', array_column($links->items(), 'id'))
            ->select();
        if (!$others->isEmpty()) {
            $others_map = [];
            $others_arr = $others->toArray();
            foreach ($others_arr as $other) {
                $product_id = $other['product_id'];
                unset($other['product_id']);
                $others_map[$product_id][] = $other;
            }
            $links->each(function ($item) use ($others_map) {
                if (!empty($others_map[$item['id']])) {
                    $item['rowspan'] = $others_map[$item['id']];
                }
                return $item;
            });
        }

        // 获取平台数据
        $platforms = ProductPurchaseLinkPlatformModel::field(['id', 'platform'])
            ->language(request()->lang_id)
            ->select()
            ->toArray();
        $platforms_map = [];
        foreach ($platforms as $k => $v) {
            $platforms_map[$v['id']] = [
                'platform_id'   => $v['id'],
                'platform_name' => $v['platform'],
                'link_id'       => 0,
                'link'          => ''
            ];
        }
        // 没有购买链接的，补全平台数据
        $links->each(function ($item) use($platforms_map) {
            if (empty($item['rowspan'])) {
                $item['rowspan'] = array_values($platforms_map);
            } else if (count($item['rowspan']) < count($platforms_map)) {
                foreach ($item['rowspan'] as $k => $v) {
                    if (!empty($platforms_map[$v['platform_id']])) {
                        unset($platforms_map[$v['platform_id']]);
                    }
                }
                $item['rowspan'] = array_merge($item['rowspan'], array_values($platforms_map));
            }
            return $item;
        });


        return success('获取成功', $links);
    }

    /**
     * 导入
     */
    public function import()
    {
        $file = request()->file('file');
        if ($file->getSize() > 20 * 1024 * 1024) {
            return error('上传文件不能超过20M');
        }

        // 从表格获取数据
        $xlsx_data = xlsx_reader($file->getRealPath(), 2, ['A' => 'spu', 'B' => 'platform', 'C' => 'link']);

        $platforms_name = array_unique(array_column($xlsx_data, 'platform'));
        $platforms_map  = ProductPurchaseLinkPlatformModel::language(request()->lang_id)
            ->where('platform', 'in', $platforms_name)
            ->column('id', 'platform');

        // 表格中spu的平台重复次数
        $spu_platform_map = [];
        foreach ($xlsx_data as $v) {
            if (!isset($spu_platform_map[$v['spu'] . '_' . $v['platform']])) {
                $spu_platform_map[$v['spu'] . '_' . $v['platform']] = 0;
            }
            $spu_platform_map[$v['spu'] . '_' . $v['platform']]++;
        }

        $data   = [];
        $errors = [];
        $chunks = array_chunk($xlsx_data, 500, true);
        // 分组验证每行，并组装数据
        foreach ($chunks as $chunk) {
            $spus = array_unique(array_column($chunk, 'spu'));
            $products_map = ProductModel::language(request()->lang_id)
                ->where('spu', 'in', $spus)
                ->column('id', 'spu');

            $items = [];
            foreach ($chunk as $r => $it) {
                if (empty($platforms_map[$it['platform']])) {
                    $errors[] = sprintf("第%d行，平台名称错误", $r);
                    continue;
                }
                if (empty($products_map[$it['spu']])) {
                    $errors[] = sprintf("第%d行，型号不存在", $r);
                    continue;
                }
                if ($spu_platform_map[$it['spu'] . '_' . $it['platform']] > 1) {
                    $errors[] = sprintf("第%d行，型号【%s】和平台【%s】有重复", $r, $it['spu'], $it['platform']);
                    continue;
                }
                $items[] = [
                    'language_id'  => request()->lang_id,
                    'product_id'   => $products_map[$it['spu']],
                    'platform_id'  => $platforms_map[$it['platform']],
                    'link'         => $it['link'],
                    'sort'         => 0,
                ];
            }
            if (!empty($items)) {
                $data[] = $items;
            }
        }
        
        // 组装sql，并执行
        if (!empty($data)) {
            $link_model = new ProductPurchaseLinkModel();
            $sql = sprintf(
                'REPLACE INTO %s (id, language_id, product_id, platform_id, link, sort) VALUES ',
                $link_model->getTable(),
            );
            foreach ($data as $items) {
                $products_id = array_unique(array_column($items, 'product_id'));
                $links = $link_model->field([
                        'id',
                        'product_id',
                        'platform_id'
                    ])
                    ->where('product_id', 'in', $products_id)
                    ->select();
                $links_map = [];
                if (!$links->isEmpty()) {
                    foreach ($links as $link) {
                        $links_map[$link['product_id'] . '_' . $link['platform_id']] = $link['id'];
                    }
                }

                foreach ($items as $item) {
                    $item['id'] =  null;
                    if (!empty($links_map[$item['product_id'] . '_' . $item['platform_id']])) {
                        $item['id'] = $links_map[$item['product_id'] . '_' . $item['platform_id']];
                    }
                    $sql .= sprintf(
                        '(%d, %d, %d, %d, "%s", %d),',
                        $item['id'],
                        $item['language_id'],
                        $item['product_id'],
                        $item['platform_id'],
                        $item['link'],
                        $item['sort']
                    );
                }
            }
            Db::execute(rtrim($sql, ','));
        }

        if (!empty($errors)) {
            return error(implode(";\n", $errors));
        }

        return success('导入成功');
    }

    /**
     * 导出
     */
    public function export()
    {
        $schema = [
            'spu'      => '型号',
            'platform' => '平台',
            'link'     => '链接'
        ];

        // 获取导出数据
        $data = $this->getExportLinkData();

        /// 导出
        return xlsx_writer($data, $schema, '产品购买链接' . date('YmdHis'));
    }
    private function getExportLinkData()
    {
        $params = request()->param([
            'name'   => '',
            'spu'    => ''
        ]);

        return ProductModel::alias('pd')
            ->field([
                'pd.spu',
                'pf.platform',
                'pl.link'
            ])
            ->leftJoin('product_purchase_link pl', 'pl.product_id = pd.id')
            ->leftJoin('product_purchase_platform pf', 'pf.id = pl.platform_id')
            ->where(function ($query) use ($params) {
                $query->where('pd.is_show', '=', 1);
                if (!empty($params['name'])) {
                    $query->where('pd.name', 'like', '%' . $params['name'] . '%');
                }
                if (!empty($params['spu'])) {
                    $query->where('pd.spu', 'like', '%' . $params['spu'] . '%');
                }
            })
            ->where('pd.language_id', '=', request()->lang_id)
            ->order(['pl.sort' => 'asc', 'pl.id' => 'desc', 'pd.id' => 'desc'])
            ->select();
    }

    /**
     * 添加购买链接
     */
    public function save()
    {
        $post = request()->post([
            'link',
            'product_id',
            'platform_id'
        ]);
        $data = [
            'link'        => $post['link'],
            'language_id' => request()->lang_id,
            'product_id'  => $post['product_id'],
            'platform_id' => $post['platform_id']
        ];
        $validate = new ProductPurchaseLinkValidate;
        if (!$validate->scene('add')->check($data)) {
            return error($validate->getError());
        }

        $link = ProductPurchaseLinkModel::create($data);
        if ($link->isEmpty()) {
            return error('操作失败');
        }
        return success('操作成功');
    }

    /**
     * 更新购买链接
     */
    public function update()
    {
        $id  = request()->param('id');
        $put = request()->put([
            'link',
            'platform_id'
        ]);

        $data = [
            'id'          => $id,
            'link'        => $put['link'],
            'language_id' => request()->lang_id,
            'platform_id' => $put['platform_id']
        ];
        $validate = new ProductPurchaseLinkValidate;
        if (!$validate->scene('edit')->check($data)) {
            return error($validate->getError());
        }

        $link = ProductPurchaseLinkModel::bypk($data['id'])->find();
        if (empty($link)) {
            return error('请确认操作对象是否存在');
        }

        if (!$link->save($data)) {
            return error('操作失败');
        }
        return success('操作成功');
    }
}
