import json
import subprocess
import sys
import threading
from datetime import datetime
from pathlib import Path

from apps.core.services.django_sys import uWSGI_Reload
from django.conf import settings
from django.contrib import admin
from django.core.management import call_command
from django.http import JsonResponse
from django.urls import path

from .models import Plugin


@admin.register(Plugin)
class PluginAdmin(admin.ModelAdmin):
    # 在admin.py中重写get_queryset方法阻止数据库查询
    def get_queryset(self, request):
        return Plugin.objects.none()  # 返回空查询集

    def has_add_permission(self, request):
        return False  # 禁用新增

    def has_change_permission(self, request):
        return False  # 禁用修改

    def has_delete_permission(self, request):
        return False  # 禁用删除

    def get_urls(self):
        urls = super().get_urls()
        custom_urls = [
            path('toggle/<str:package>/',
                 self.toggle_plugin,
                 name='plugin_toggle'),
            path('migrate/<str:package>/',
                 self.migrate_plugin,
                 name='plugin_migrate'),
            path('install_deps/<str:package>/',
                 self.install_dependencies,
                 name='plugin_install_deps')
        ]
        return custom_urls + urls

    def install_dependencies(self, request, package):
        plugin_dir = Path(settings.PLUGINS_DIR) / package
        requirements_file = plugin_dir / 'requirements.txt'

        try:
            if not requirements_file.exists():

                return JsonResponse({
                    'status':
                    'error',
                    'message':
                    'requirements.txt文件缺失，请联系开发者补充文件'
                })

            # 执行依赖安装
            result = subprocess.run([
                sys.executable, '-m', 'pip', 'install', '-r',
                str(requirements_file)
            ],
                                    capture_output=True,
                                    text=True)

            # 更新元数据
            with open(plugin_dir / 'plugin_meta.json', 'r+',
                      encoding='utf-8') as f:
                meta = json.load(f)
                meta['dependency_status'] = 'installed'
                meta['last_dependency_check'] = datetime.now().isoformat()
                f.seek(0)
                json.dump(meta, f, indent=4, ensure_ascii=False)
                f.truncate()

            return JsonResponse({
                'status': 'success',
                'output': result.stdout,
                'error': result.stderr
            })
        except Exception as e:
            # 标记为安装失败
            with open(plugin_dir / 'plugin_meta.json', 'r+',
                      encoding='utf-8') as f:
                meta = json.load(f)
                meta['dependency_status'] = 'pending'
                f.seek(0)
                json.dump(meta, f, indent=4, ensure_ascii=False)
                f.truncate()
            return JsonResponse({
                'status': 'error',
                'message': str(e)
            },
                                status=500)

    def migrate_plugin(self, request, package):
        plugin_dir = Path(settings.PLUGINS_DIR) / package
        try:
            call_command('makemigrations', package)
            call_command('migrate', package)
            # 更新迁移状态为completed
            # 可选值: "not_required", "pending", "completed"
            with open(plugin_dir / 'plugin_meta.json', 'r+',
                      encoding='utf-8') as f:
                meta = json.load(f)
                # 更新元数据
                meta['migration_status'] = 'completed'
                f.seek(0)
                json.dump(meta, f, indent=4, ensure_ascii=False)
                f.truncate()
            return JsonResponse({'status': 'success'})
        except Exception as e:
            print('migrate_plugin Error:', e)
            return JsonResponse({'status': 'error', 'message': str(e)})

    def toggle_plugin(self, request, package):
        try:
            plugin_dir = Path(settings.PLUGINS_DIR) / package
            if not plugin_dir.exists():
                raise FileNotFoundError(f"Plugin {package} not found")

            with open(plugin_dir / 'plugin_meta.json', 'r+',
                      encoding='utf-8') as f:
                meta = json.load(f)
                new_status = not meta.get('is_active', False)

                # 更新元数据
                meta['is_active'] = new_status
                f.seek(0)
                json.dump(meta, f, indent=4, ensure_ascii=False)
                f.truncate()
            thread = threading.Thread(target=uWSGI_Reload)
            thread.start()

            return JsonResponse({'status': 'success', 'is_active': new_status})
        except Exception as e:
            return JsonResponse({
                'status': 'error',
                'message': str(e)
            },
                                status=500)

    def changelist_view(self, request, extra_context=None):
        extra_context = extra_context or {}
        from apps.core.utils.djacore import get_service_status_info
        extra_context.update({
            'plugins': self.model.get_plugins(),
            'title': '插件管理',
            'opts': self.model._meta,
            'auth_mes': get_service_status_info()
        })
        return super().changelist_view(request, extra_context)
