import * as fs from 'fs';
import * as path from 'path';
import type { IncomingMessage, ServerResponse } from 'http';
import type { Plugin } from 'vite';

/**
 * Dev-only Vite plugin for Gadmin2 Dev Tools.
 *
 * Features:
 * 1. POST /canvas-patch — agent pushes new component code to canvas via HMR
 * 2. "/" serves dev-shell-entry.html (agent panel outer shell)
 * 3. All other HTML navigation falls back to index.html (SPA router)
 */
export function devShellPlugin(): Plugin {
  return {
    name: 'dev-shell',
    apply: 'serve',
    configureServer(server) {
      server.middlewares.use(async (rawReq, rawRes, next) => {
        const req = rawReq as IncomingMessage;
        const res = rawRes as ServerResponse;
        const url = req.url?.split('?')[0] ?? '/';

        // POST /canvas-patch — agent 将新组件代码通过 HMR 推送给前端画布
        if (req.method === 'POST' && url === '/canvas-patch') {
          let body = '';
          req.on('data', (chunk: Buffer) => {
            body += chunk.toString();
          });
          req.on('end', () => {
            try {
              const { itemId, code } = JSON.parse(body) as {
                itemId: string;
                code: string;
              };
              if (itemId && code !== undefined) {
                server.hot.send('canvas:patch', { itemId, code });
                res.setHeader('Content-Type', 'application/json');
                res.end(JSON.stringify({ ok: true }));
              } else {
                res.statusCode = 400;
                res.end(JSON.stringify({ error: 'itemId and code required' }));
              }
            } catch {
              res.statusCode = 400;
              res.end(JSON.stringify({ error: 'invalid JSON' }));
            }
          });
          return;
        }

        // "/" → dev-shell-entry.html（Agent 外壳）
        if (url === '/') {
          const rawHtml = fs.readFileSync(
            path.resolve(__dirname, '..', '..', 'dev-shell-entry.html'),
            'utf-8',
          );
          const html = await server.transformIndexHtml(url, rawHtml);
          res.setHeader('Content-Type', 'text/html');
          res.end(html);
          return;
        }

        // 其他 HTML 导航请求 → index.html（SPA fallback）
        const lastSegment = url.split('/').pop() ?? '';
        const isAsset = lastSegment.includes('.');
        const isHtmlNav =
          !isAsset && (req.headers.accept ?? '').includes('text/html');
        if (isHtmlNav) {
          const rawHtml = fs.readFileSync(
            path.resolve(__dirname, '..', '..', 'index.html'),
            'utf-8',
          );
          const html = await server.transformIndexHtml(url, rawHtml);
          res.setHeader('Content-Type', 'text/html');
          res.end(html);
          return;
        }

        next();
      });
    },
  };
}
