<?php

namespace App\Admin\Forms;

use App\Admin\Renderable\DistDistributorTable;
use App\Admin\Repositories\DistAdminDistributor;
use App\Admin\Repositories\DistAppearance;
use App\Admin\Repositories\DistAppearancePublishList;
use App\Admin\Repositories\DistAppearanceTemplate;
use App\Admin\Repositories\DistInquiry;
use Dcat\Admin\Models\DistAdminUser;
use Dcat\Admin\Widgets\Form;
use Dcat\Admin\Contracts\LazyRenderable;
use Dcat\Admin\Traits\LazyWidget;
use ZipArchive;

class AppearanceImPortForm extends Form implements LazyRenderable
{
    use LazyWidget;

    protected $appearanceId = 0;

    // 处理请求
    public function handle(array $input)
    {
        // 获取外部传递参数
        $appearanceId = $this->payload['id'] ?? null;
        $file = $input['file'] ?? null;
        $appearanceRs = DistAppearance::getOneById($appearanceId);
        if ($file && $appearanceRs) {
            $folder = $appearanceRs->folder;
            $extractPath = resource_path().'/appearance/tmp';
            $path = resource_path().'/appearance/'.$folder;
            //解压
            $unzip = $this->unzip($file,$extractPath,$path);
            if (!$unzip['status']) {
                return $this->response()->error($unzip['error']);
            }
            //导入模板
            if (!is_dir($path)) {
                return $this->response()->error("The directory does not exist")->refresh();
            }
            $this->sourcePath = $path;
            $this->appearanceId = $appearanceId;
            // 清空旧的
            DistAppearanceTemplate::deleteTemplates($appearanceId, config('dictionary.base_dist_id'));
            // 导入模板
            $this->readDirectory($path);
            //发报到正式环境
            DistAppearancePublishList::publish($appearanceId,config('dictionary.base_dist_id'));
            // 更新状态
            DistAppearance::setStatusToImported($appearanceId);
            return $this->response()->success('allocation successful')->refresh();
        }
        return $this->response()->error('No file data');
    }

    /*
     * 下载并解压
     */

    private function unzip($savePath,$extractPath,$trulyPath)
    {
        // 检查 $extractPath 是否存在且是否是一个目录
        if (!is_dir($extractPath)) {
            mkdir($extractPath, 0755, true);
        }

        if (!is_dir($trulyPath)) {
            mkdir($trulyPath, 0755, true);
        }

        $savePath = storage_path().'/app/'.$savePath;
        // 检查是否支持 ZipArchive 扩展
        if (!extension_loaded('zip')) {
            return ['status' => false, 'error' => 'ZipArchive 扩展未加载'];
        }
        // 保存文件到本地
        $zip = new ZipArchive;
        if ($zip->open($savePath) !== TRUE) {
            return ['status' => false, 'error' => 'ZipArchive 解压失败'];
        }
        if ($zip->extractTo($extractPath) !== TRUE) {
            return ['status' => false, 'error' => "解压文件到 $extractPath 失败。"];
        }
        $zip->close();
        //解压后,停0.1秒
        usleep(100000);
        //判断tmp下是否只有一个文件夹,如果是,移动到trulyPath
        // 递归删除 $trulyPath 下的所有文件和文件夹
        $deleteDirectoryContents = $this->deleteDirectoryContents($trulyPath);
        if ($deleteDirectoryContents) {
            return ['status' => false, 'error' => $deleteDirectoryContents];
        }
        // 获取 $extractPath 下的所有文件和文件夹
        $items = scandir($extractPath);
        // 过滤掉 '.' 和 '..'
        $items = array_diff($items, ['.', '..']);
        // 判断 $extractPath 是否只有一个文件夹
        if (count($items) != 1) {
            return ['status' => false, 'error' => "Error: unzip file does not contain exactly one folder."];
        }
        // 获取文件夹名称
        $folderName = reset($items);
        $folderPath = $extractPath . '/' . $folderName;
        // 获取文件夹下的所有文件和文件夹
        $folderContents = scandir($folderPath);
        $folderContents = array_diff($folderContents, ['.', '..']);
        // 将文件夹中的所有内容移动到 $trulyPath
        foreach ($folderContents as $fileOrDir) {
            $sourcePath = $folderPath . '/' . $fileOrDir;
            $destinationPath = $trulyPath . '/' . $fileOrDir;
            // 如果是文件,移动文件
            if (is_file($sourcePath)) {
                if (!rename($sourcePath, $destinationPath)) {
                    return ['status' => false, 'error' => "Error: Failed to move file $fileOrDir\n"];
                }
            }
            // 如果是目录,递归移动目录内容
            elseif (is_dir($sourcePath)) {
                // 创建目标文件夹
                if (!mkdir($destinationPath)) {
                    return ['status' => false, 'error' => "Error: Failed to create folder $fileOrDir\n"];
                }
                // 递归移动文件夹内容
                $folderFiles = scandir($sourcePath);
                $folderFiles = array_diff($folderFiles, ['.', '..']);
                foreach ($folderFiles as $subFile) {
                    $subSourcePath = $sourcePath . '/' . $subFile;
                    $subDestinationPath = $destinationPath . '/' . $subFile;
                    if (!rename($subSourcePath, $subDestinationPath)) {
                        return ['status' => false, 'error' => "Error: Failed to move subfolder file $subFile\n"];
                    }
                }
            }
        }
        // 删除原文件夹及其内容
        $this->deleteDirectoryContents($folderPath);
        return ['status' => true];
    }

    // 递归删除文件夹及其内容
    private function deleteDirectoryContents($dir)
    {
        // 获取目录下所有文件和文件夹
        $items = scandir($dir);

        // 过滤掉 '.' 和 '..'
        $items = array_diff($items, ['.', '..']);

        // 循环遍历目录下的每一项
        foreach ($items as $item) {
            $itemPath = $dir . '/' . $item;

            // 如果是文件,删除文件
            if (is_file($itemPath)) {
                if (!unlink($itemPath)) {
                    return "Error: Failed to delete file $itemPath\n";
                }
            }
            // 如果是目录,递归删除该目录
            elseif (is_dir($itemPath)) {
                $this->deleteDirectoryContents($itemPath); // 递归删除目录内容
                if (!rmdir($itemPath)) {
                    return "Error: Failed to delete directory $itemPath\n";
                }
            }
        }
    }



    public function form()
    {
        $this->file('file')
            ->disk('local') // 使用本地存储
            ->uniqueName()
            ->autoUpload()
            ->required()
            ->accept('zip')
            ->dir(config("admin.upload.directory.file").'/tmp/')
            ->help('Please upload a zip file');

    }
    private function readDirectory($dirPath) {
        // 检查目录是否存在
        if (!is_dir($dirPath)) {
            return;
        }

        // 打开目录
        $dir = opendir($dirPath);

        // 读取目录内容
        while (($file = readdir($dir)) !== false) {
            // 忽略当前目录和上级目录
            if ($file == '.' || $file == '..') {
                continue;
            }

            // 获取文件或文件夹的完整路径
            $fullPath = $dirPath . '/' . $file;

            // 如果是文件夹,递归读取
            if (is_dir($fullPath)) {
                $this->readDirectory($fullPath); // 递归调用
            } else {
                // 如果是文件,读取文件内容
                $content = file_get_contents($fullPath);
                $filePath = str_replace($this->sourcePath, '', $dirPath);
                $filePath = trim($filePath, '/');
                $fileName = basename($fullPath);
                // 插入数据库
                DistAppearanceTemplate::insertTemplateContent(config('dictionary.base_dist_id'), $this->appearanceId, $filePath,$fileName, $content);
            }
        }

        // 关闭目录
        closedir($dir);
    }


}