/** @jsxImportSource https://esm.d8d.fun/hono@4.7.4/jsx */
import { Hono } from 'hono'
import { Auth } from '@d8d-appcontainer/auth'
import type { User as AuthUser } from '@d8d-appcontainer/auth'
import React from 'hono/jsx'
import type { FC } from 'hono/jsx'
import { cors } from 'hono/cors'
import type { Context as HonoContext } from 'hono'
import { serveStatic } from 'hono/deno'
import { APIClient } from '@d8d-appcontainer/api'
import debug from "debug"
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import type { SystemSettingRecord, GlobalConfig } from '../client/share/types.ts';
import { SystemSettingKey, OssType, MapMode } from '../client/share/types.ts';

import {
  createKnowInfoRoutes,
  createFileCategoryRoutes,
  createFileUploadRoutes,
  createThemeRoutes,
  createSystemSettingsRoutes,
} from "./routes_sys.ts";

import {
  createMapRoutes,
} from "./routes_maps.ts";

import {
  createChartRoutes,
} from "./routes_charts.ts";

// 导入基础路由
import { createAuthRoutes } from "./routes_auth.ts";
import { createUserRoutes } from "./routes_users.ts";
import { createMessagesRoutes } from "./routes_messages.ts";
import { createMigrationsRoutes } from "./routes_migrations.ts";
import { createHomeRoutes } from "./routes_home.ts";
dayjs.extend(utc)
// 初始化debug实例
const log = {
  app: debug('app:server'),
  auth: debug('auth:server'),
  api: debug('api:server'),
  debug: debug('debug:server')
}

const GLOBAL_CONFIG: GlobalConfig = {
  OSS_BASE_URL: Deno.env.get('OSS_BASE_URL') || 'https://d8d-appcontainer-user.oss-cn-beijing.aliyuncs.com',
  OSS_TYPE: Deno.env.get('OSS_TYPE') === OssType.MINIO ? OssType.MINIO : OssType.ALIYUN,
  API_BASE_URL: '/api',
  APP_NAME: Deno.env.get('APP_NAME') || '应用Starter',
  ENV: Deno.env.get('ENV') || 'development',
  DEFAULT_THEME: 'light', // 默认主题
  MAP_CONFIG: {
    KEY: Deno.env.get('AMAP_KEY') || '您的地图API密钥',
    VERSION: '2.0',
    PLUGINS: ['AMap.ToolBar', 'AMap.Scale', 'AMap.HawkEye', 'AMap.MapType', 'AMap.Geolocation'],
    MAP_MODE: Deno.env.get('MAP_MODE') === MapMode.OFFLINE ? MapMode.OFFLINE : MapMode.ONLINE,
  },
  CHART_THEME: 'default', // 图表主题
  ENABLE_THEME_CONFIG: false, // 主题配置开关
  THEME: null
};

log.app.enabled = true
log.auth.enabled = true
log.api.enabled = true
log.debug.enabled = true

// 定义自定义上下文类型
export interface Variables {
  auth: Auth
  user?: AuthUser
  apiClient: APIClient
  moduleDir: string
  systemSettings?: SystemSettingRecord
}

// 定义登录历史类型
interface LoginHistory {
  id: number
  user_id: number
  login_time: string
  ip_address?: string
  user_agent?: string
}

// 定义仪表盘数据类型
interface DashboardData {
  lastLogin: string
  loginCount: number
  fileCount: number
  userCount: number
  systemInfo: {
    version: string
    lastUpdate: string
  }
}

interface EsmScriptConfig {
  src: string
  href: string
  denoJson: string
  refresh: boolean
  prodPath?: string
  prodSrc?: string
}

// Auth实例
let authInstance: Auth | null = null

// 初始化Auth实例
const initAuth = async (apiClient: APIClient) => {
  try {
    if (authInstance) {
      return authInstance
    }

    log.auth('正在初始化Auth实例')
    
    authInstance = new Auth(apiClient as any, {
      jwtSecret: Deno.env.get("JWT_SECRET") || 'your-jwt-secret-key',
      initialUsers: [],
      storagePrefix: '',
      userTable: 'users',
      fieldNames: {
        id: 'id',
        username: 'username',
        password: 'password',
        phone: 'phone',
        email: 'email',
        is_disabled: 'is_disabled',
        is_deleted: 'is_deleted'
      },
      tokenExpiry: 24 * 60 * 60,
      refreshTokenExpiry: 7 * 24 * 60 * 60
    })
    
    log.auth('Auth实例初始化完成')
    
    return authInstance
  } catch (error) {
    log.auth('Auth初始化失败:', error)
    throw error
  }
}

// 初始化系统设置
const initSystemSettings = async (apiClient: APIClient) => {
  try {
    const systemSettings = await apiClient.database.table('system_settings')
      .select()
    
    // 将系统设置转换为键值对形式
    const settings = systemSettings.reduce((acc: Record<string, any>, setting: any) => {
      acc[setting.key] = setting.value
      return acc
    }, {}) as SystemSettingRecord
    
    // 更新全局配置
    if (settings[SystemSettingKey.SITE_NAME]) {
      GLOBAL_CONFIG.APP_NAME = String(settings[SystemSettingKey.SITE_NAME])
    }
    
    // 设置其他全局配置项
    if (settings[SystemSettingKey.SITE_FAVICON]) {
      GLOBAL_CONFIG.DEFAULT_THEME = String(settings[SystemSettingKey.SITE_FAVICON])
    }
    
    if (settings[SystemSettingKey.SITE_LOGO]) {
      GLOBAL_CONFIG.MAP_CONFIG.KEY = String(settings[SystemSettingKey.SITE_LOGO])
    }
    
    if (settings[SystemSettingKey.SITE_DESCRIPTION]) {
      GLOBAL_CONFIG.CHART_THEME = String(settings[SystemSettingKey.SITE_DESCRIPTION])
    }

    // 设置主题配置开关
    if (settings[SystemSettingKey.ENABLE_THEME_CONFIG]) {
      GLOBAL_CONFIG.ENABLE_THEME_CONFIG = settings[SystemSettingKey.ENABLE_THEME_CONFIG] === 'true'
    }

    // 查询ID1管理员的主题配置
    const adminTheme = await apiClient.database.table('theme_settings')
      .where('user_id', 1)
      .first()
    
    if (adminTheme) {
      GLOBAL_CONFIG.THEME = adminTheme.settings
    }
    
    return settings
    
  } catch (error) {
    log.app('获取系统设置失败:', error)
    return {} as SystemSettingRecord
  }
}

// 中间件：验证认证
const withAuth = async (c: HonoContext<{ Variables: Variables }>, next: () => Promise<void>) => {
  try {
    const auth = c.get('auth')
    
    const token = c.req.header('Authorization')?.replace('Bearer ', '')
    if (token) {
      const userData = await auth.verifyToken(token)
      if (userData) {
        c.set('user', userData)
        await next()
        return
      }
    }
    
    return c.json({ error: '未授权' }, 401)
  } catch (error) {
    log.auth('认证失败:', error)
    return c.json({ error: '无效凭证' }, 401)
  }
}

// 导出withAuth类型定义
export type WithAuth = typeof withAuth;

// 定义模块参数接口
interface ModuleParams {
  apiClient: APIClient
  app: Hono<{ Variables: Variables }>
  moduleDir: string
}

export default function({ apiClient, app, moduleDir }: ModuleParams) {
  const honoApp = app
  // 添加CORS中间件
  honoApp.use('/*', cors())
  
  // 创建API路由
  const api = new Hono<{ Variables: Variables }>()


  // // 使用数据库中间件
  // api.use('/*', withDatabase)

  // 设置环境变量
  api.use('*', async (c, next) => {
    c.set('apiClient', apiClient)
    c.set('moduleDir', moduleDir)
    c.set('auth', await initAuth(apiClient))
    c.set('systemSettings', await initSystemSettings(apiClient))
    await next()
  })

  // 查询仪表盘数据
  api.get('/dashboard', withAuth, async (c) => {
    try {
      const user = c.get('user')!
      const apiClient = c.get('apiClient')
      const lastLogin = await apiClient.database.table('login_history')
        .where('user_id', user.id)
        .orderBy('login_time', 'desc')
        .limit(1)
        .first()
      
      // 获取登录总次数
      const loginCount = await apiClient.database.table('login_history')
        .where('user_id', user.id)
        .count()
      
      // 获取系统数据统计
      const fileCount = await apiClient.database.table('file_library')
        .where('is_deleted', 0)
        .count()
        
      const userCount = await apiClient.database.table('users')
        .where('is_deleted', 0)
        .count()
        
      // 返回仪表盘数据
      const dashboardData: DashboardData = {
        lastLogin: lastLogin ? lastLogin.login_time : new Date().toISOString(),
        loginCount: loginCount,
        fileCount: Number(fileCount),
        userCount: Number(userCount),
        systemInfo: {
          version: '1.0.0',
          lastUpdate: new Date().toISOString()
        }
      }
      
      return c.json(dashboardData)
    } catch (error) {
      log.api('获取仪表盘数据失败:', error)
      return c.json({ error: '获取仪表盘数据失败' }, 500)
    }
  })
  // 注册基础路由
  api.route('/auth', createAuthRoutes(withAuth))
  api.route('/users', createUserRoutes(withAuth))
  api.route('/know-infos', createKnowInfoRoutes(withAuth))
  api.route('/upload', createFileUploadRoutes(withAuth)) // 添加文件上传路由
  api.route('/file-categories', createFileCategoryRoutes(withAuth)) // 添加文件分类管理路由
  api.route('/theme', createThemeRoutes(withAuth)) // 添加主题设置路由
  api.route('/charts', createChartRoutes(withAuth)) // 添加图表数据路由
  api.route('/map', createMapRoutes(withAuth)) // 添加地图数据路由
  api.route('/settings', createSystemSettingsRoutes(withAuth)) // 添加系统设置路由
  api.route('/messages', createMessagesRoutes(withAuth)) // 添加消息路由
  api.route('/migrations', createMigrationsRoutes(withAuth)) // 添加数据库迁移路由
  api.route('/home', createHomeRoutes(withAuth)) // 添加首页路由
  
  // 注册API路由
  honoApp.route('/api', api)
 
  // 首页路由 - SSR
  honoApp.get('/', async (c: HonoContext) => {
    const systemName = GLOBAL_CONFIG.APP_NAME
    return c.html(
      <html>
        <head>
          <title>{systemName}</title>
          <meta charset="UTF-8" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <script src="https://cdn.tailwindcss.com"></script>
        </head>
        <body>
          <div className="min-h-screen bg-gray-50 flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
            <div className="max-w-md w-full space-y-8">
              {/* 系统介绍区域 */}
              <div className="text-center">
                <h1 className="text-4xl font-bold text-gray-900 mb-4">
                  {systemName}
                </h1>
                <p className="text-lg text-gray-600 mb-8">
                  全功能应用Starter
                </p>
                <p className="text-base text-gray-500 mb-8">
                  这是一个基于Hono和React的应用Starter，提供了用户认证、文件管理、图表分析、地图集成和主题切换等常用功能。
                </p>
              </div>

              {/* 管理入口按钮 */}
              <div className="space-y-4">
                <a
                  href="/admin"
                  className="w-full flex justify-center py-3 px-4 border border-transparent rounded-md shadow-sm text-lg font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
                >
                  进入管理后台
                </a>
                
                {/* 移动端入口按钮 */}
                <a
                  href="/mobile"
                  className="w-full flex justify-center py-3 px-4 border border-blue-600 rounded-md shadow-sm text-lg font-medium text-blue-600 bg-white hover:bg-blue-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
                >
                  进入移动端
                </a>
              </div>
            </div>
          </div>
         </body>
      </html>
    )
  })
  
  // 创建一个函数，用于生成包含全局配置的HTML页面
  const createHtmlWithConfig = (scriptConfig: EsmScriptConfig, title = '应用Starter') => {
    return (c: HonoContext) => {
      const isProd = GLOBAL_CONFIG.ENV === 'production';
      
      return c.html(
        <html lang="zh-CN">
          <head>
            <meta charset="UTF-8" />
            <meta name="viewport" content="width=device-width, initial-scale=1.0" />
            <title>{title}</title>
            
            {isProd ? (
              <script type="module" src={scriptConfig.prodSrc || `/client_dist/${scriptConfig.prodPath}`}></script>
            ) : (
              <script src={scriptConfig.src} href={scriptConfig.href} deno-json={scriptConfig.denoJson} refresh={scriptConfig.refresh}></script>
            )}
            
            {isProd ? (<script src="/tailwindcss@3.4.16/index.js"></script>) : (<script src="https://cdn.tailwindcss.com"></script>)}

            <script dangerouslySetInnerHTML={{ __html: `window.CONFIG = ${JSON.stringify(GLOBAL_CONFIG)};` }} />
            
            {!isProd && (
              <>
                <script src="https://ai-oss.d8d.fun/umd/vconsole.3.15.1.min.js"></script>
                <script dangerouslySetInnerHTML={{ __html: `
                  const urlParams = new URLSearchParams(window.location.search);
                  if (urlParams.has('vconsole')) {
                    var vConsole = new VConsole({
                      theme: urlParams.get('vconsole_theme') || 'light',
                      onReady: function() {
                        console.log('vConsole is ready');
                      }
                    });
                  }
                `}} />
              </>
            )}
          </head>
          <body className="bg-gray-50">
            <div id="root"></div>
          </body>
        </html>
      )
    }
  }

  // 后台管理路由
  honoApp.get('/admin', createHtmlWithConfig({
    src: "https://esm.d8d.fun/xb", 
    href: "/client/admin/web_app.tsx", 
    denoJson: "/deno.json", 
    refresh: true, 
    prodPath: "admin/web_app.js"
  }, GLOBAL_CONFIG.APP_NAME))
  
  honoApp.get('/admin/*', createHtmlWithConfig({
    src: "https://esm.d8d.fun/xb", 
    href: "/client/admin/web_app.tsx", 
    denoJson: "/deno.json", 
    refresh: true, 
    prodPath: "admin/web_app.js"
  }, GLOBAL_CONFIG.APP_NAME))

  // 移动端路由
  honoApp.get('/mobile', createHtmlWithConfig({
    src: "https://esm.d8d.fun/xb", 
    href: "/client/mobile/mobile_app.tsx", 
    denoJson: "/deno.json", 
    refresh: true, 
    prodPath: "mobile/mobile_app.js"
  }, GLOBAL_CONFIG.APP_NAME))
  
  honoApp.get('/mobile/*', createHtmlWithConfig({
    src: "https://esm.d8d.fun/xb", 
    href: "/client/mobile/mobile_app.tsx", 
    denoJson: "/deno.json", 
    refresh: true, 
    prodPath: "mobile/mobile_app.js"
  }, GLOBAL_CONFIG.APP_NAME))

  const staticRoutes = serveStatic({ 
    root: moduleDir,
    onFound: async (path: string, c: HonoContext) => {
      const fileExt = path.split('.').pop()?.toLowerCase()
      if (fileExt === 'tsx' || fileExt === 'ts') {
        c.header('Content-Type', 'text/typescript; charset=utf-8')
      } else if (fileExt === 'js' || fileExt === 'mjs') {
        c.header('Content-Type', 'application/javascript; charset=utf-8')
      } else if (fileExt === 'json') {
        c.header('Content-Type', 'application/json; charset=utf-8')
      } else if (fileExt === 'html') {
        c.header('Content-Type', 'text/html; charset=utf-8')
      } else if (fileExt === 'css') {
        c.header('Content-Type', 'text/css; charset=utf-8')
      } else if (['jpg', 'jpeg', 'png', 'gif', 'webp'].includes(fileExt || '')) {
        c.header('Content-Type', `image/${fileExt}`)
      }
      const fileInfo = await Deno.stat(path)
      c.header('Last-Modified', fileInfo.mtime?.toUTCString() ?? new Date().toUTCString())
    },
  })
  
  // 静态资源路由
  honoApp.get('/deno.json', staticRoutes)
  honoApp.get('/client/*', staticRoutes)
  honoApp.get('/amap/*', staticRoutes)
  honoApp.get('/tailwindcss@3.4.16/*', staticRoutes)
  honoApp.get('/client_dist/*', staticRoutes)
  
  return honoApp
}
