import type { Plugin } from 'vite';
import fs from 'fs';
import path from 'path';

import { getRequestPathname, readJsonBody } from './utils/httpUtils';

export function themesApiPlugin(): Plugin {
  return {
    name: 'themes-api-plugin',
    configureServer(server: any) {
      server.middlewares.use((req: any, res: any, next: any) => {
        const pathname = getRequestPathname(req);
        if (!pathname.startsWith('/api/themes')) {
          return next();
        }

        // Sync a theme's DESIGN.md to the project root
        if (req.method === 'POST' && pathname === '/api/themes/sync-design') {
          (async () => {
            try {
              const body = await readJsonBody(req);
              const themeName = (body?.themeName || '').trim();
              const rootDesignPath = path.resolve(process.cwd(), 'DESIGN.md');

              if (!themeName) {
                // Clear: remove root DESIGN.md if it exists
                if (fs.existsSync(rootDesignPath)) {
                  fs.unlinkSync(rootDesignPath);
                }
                res.statusCode = 200;
                res.setHeader('Content-Type', 'application/json');
                res.end(JSON.stringify({ success: true, removed: true }));
                return;
              }

              const themesDir = path.resolve(process.cwd(), 'src/themes');
              const themeDesignPath = path.join(themesDir, themeName, 'DESIGN.md');

              if (!themeDesignPath.startsWith(themesDir)) {
                res.statusCode = 403;
                res.end(JSON.stringify({ error: 'Forbidden' }));
                return;
              }

              if (!fs.existsSync(themeDesignPath)) {
                // Theme has no DESIGN.md — remove root copy if present
                if (fs.existsSync(rootDesignPath)) {
                  fs.unlinkSync(rootDesignPath);
                }
                res.statusCode = 200;
                res.setHeader('Content-Type', 'application/json');
                res.end(JSON.stringify({ success: true, skipped: true }));
                return;
              }

              fs.copyFileSync(themeDesignPath, rootDesignPath);
              res.statusCode = 200;
              res.setHeader('Content-Type', 'application/json');
              res.end(JSON.stringify({ success: true }));
            } catch (error: any) {
              console.error('Error syncing DESIGN.md:', error);
              res.statusCode = 500;
              res.end(JSON.stringify({ error: error.message }));
            }
          })();
          return;
        }

        if (req.method === 'DELETE' && pathname !== '/api/themes' && pathname !== '/api/themes/') {
          try {
            const themeName = pathname.replace('/api/themes/', '');
            if (!themeName) {
              res.statusCode = 400;
              res.end(JSON.stringify({ error: 'Missing theme name' }));
              return;
            }

            const themesDir = path.resolve(process.cwd(), 'src/themes');
            const themeDir = path.join(themesDir, themeName);

            if (!themeDir.startsWith(themesDir)) {
              res.statusCode = 403;
              res.end(JSON.stringify({ error: 'Forbidden' }));
              return;
            }

            if (!fs.existsSync(themeDir)) {
              res.statusCode = 404;
              res.end(JSON.stringify({ error: 'Theme not found' }));
              return;
            }

            fs.rmSync(themeDir, { recursive: true, force: true });
            res.statusCode = 200;
            res.setHeader('Content-Type', 'application/json');
            res.end(JSON.stringify({ success: true }));
          } catch (error: any) {
            console.error('Error deleting theme:', error);
            res.statusCode = 500;
            res.end(JSON.stringify({ error: error.message }));
          }
          return;
        }

        if (req.method === 'PUT' && pathname !== '/api/themes' && pathname !== '/api/themes/') {
          (async () => {
            try {
              const themeName = pathname.replace('/api/themes/', '');
              if (!themeName) {
                res.statusCode = 400;
                res.end(JSON.stringify({ error: 'Missing theme name' }));
                return;
              }

              const body = await readJsonBody(req);
              const displayName = (body?.displayName || '').trim();
              if (!displayName) {
                res.statusCode = 400;
                res.end(JSON.stringify({ error: 'Missing displayName' }));
                return;
              }

              const themesDir = path.resolve(process.cwd(), 'src/themes');
              const themeDir = path.join(themesDir, themeName);

              if (!themeDir.startsWith(themesDir)) {
                res.statusCode = 403;
                res.end(JSON.stringify({ error: 'Forbidden' }));
                return;
              }

              if (!fs.existsSync(themeDir)) {
                res.statusCode = 404;
                res.end(JSON.stringify({ error: 'Theme not found' }));
                return;
              }

              const designTokenPath = path.join(themeDir, 'designToken.json');
              let designToken: any = {};
              if (fs.existsSync(designTokenPath)) {
                try {
                  designToken = JSON.parse(fs.readFileSync(designTokenPath, 'utf8'));
                } catch (error: any) {
                  res.statusCode = 400;
                  res.end(JSON.stringify({ error: error.message || 'Invalid designToken.json' }));
                  return;
                }
              }

              designToken.name = displayName;
              fs.writeFileSync(designTokenPath, JSON.stringify(designToken, null, 2));

              res.statusCode = 200;
              res.setHeader('Content-Type', 'application/json');
              res.end(JSON.stringify({ success: true }));
            } catch (error: any) {
              console.error('Error updating theme name:', error);
              res.statusCode = 500;
              res.end(JSON.stringify({ error: error.message }));
            }
          })();
          return;
        }

        if (req.method !== 'GET') {
          return next();
        }

        if (pathname !== '/api/themes' && pathname !== '/api/themes/') {
          try {
            const themeName = pathname.replace('/api/themes/', '');
            if (!themeName) {
              return next();
            }

            const themesDir = path.resolve(process.cwd(), 'src/themes');
            const themeDir = path.join(themesDir, themeName);

            if (!themeDir.startsWith(themesDir)) {
              res.statusCode = 403;
              res.end(JSON.stringify({ error: 'Forbidden' }));
              return;
            }

            if (fs.existsSync(themeDir) && fs.statSync(themeDir).isDirectory()) {
              const designTokenPath = path.join(themeDir, 'designToken.json');
              const indexHtmlPath = path.join(themeDir, 'index.html');

              const themeData: any = { name: themeName, displayName: themeName };

              if (fs.existsSync(designTokenPath)) {
                try {
                  const designToken = JSON.parse(fs.readFileSync(designTokenPath, 'utf8'));
                  themeData.designToken = designToken;
                  if (designToken && designToken.name) {
                    themeData.displayName = designToken.name;
                  }
                } catch (error) {
                  console.error('Error parsing designToken.json:', error);
                }
              }

              if (fs.existsSync(indexHtmlPath)) {
                themeData.indexHtml = fs.readFileSync(indexHtmlPath, 'utf8');
              }

              res.setHeader('Content-Type', 'application/json');
              res.end(JSON.stringify(themeData));
            } else {
              res.statusCode = 404;
              res.end(JSON.stringify({ error: 'Theme not found' }));
            }
          } catch (error: any) {
            console.error('Error loading theme:', error);
            res.statusCode = 500;
            res.end(JSON.stringify({ error: error.message }));
          }
          return;
        }

        try {
          const themesDir = path.resolve(process.cwd(), 'src/themes');
          const themes: any[] = [];

          if (fs.existsSync(themesDir)) {
            const items = fs.readdirSync(themesDir, { withFileTypes: true });

            items.forEach((item) => {
              if (item.isDirectory()) {
                const themeDir = path.join(themesDir, item.name);
                const designTokenPath = path.join(themeDir, 'designToken.json');
                const globalsPath = path.join(themeDir, 'globals.css');
                const designSpecPath = path.join(themeDir, 'DESIGN.md');
                const indexTsxPath = path.join(themeDir, 'index.tsx');
                let displayName = item.name;
                const hasDesignToken = fs.existsSync(designTokenPath);
                const hasGlobals = fs.existsSync(globalsPath);
                const hasDesignSpec = fs.existsSync(designSpecPath);
                const hasIndexTsx = fs.existsSync(indexTsxPath);

                if (hasDesignToken) {
                  try {
                    const designToken = JSON.parse(fs.readFileSync(designTokenPath, 'utf8'));
                    if (designToken && designToken.name) {
                      displayName = designToken.name;
                    }
                  } catch (error) {
                    console.error(`Error loading theme ${item.name} designToken:`, error);
                  }
                }

                let description = '';
                let hasDoc = false;
                const readmePath = path.join(themeDir, 'README.md');

                if (fs.existsSync(readmePath)) {
                  try {
                    const content = fs.readFileSync(readmePath, 'utf8');
                    const firstLine = content.split('\n')[0];
                    description = firstLine.replace(/^#\s*/, '').trim();
                    hasDoc = true;
                  } catch (error) {
                    console.warn(`Failed to read README.md for ${item.name}:`, error);
                  }
                } else if (fs.existsSync(designSpecPath)) {
                  try {
                    const content = fs.readFileSync(designSpecPath, 'utf8');
                    const firstLine = content.split('\n')[0];
                    description = firstLine.replace(/^#\s*/, '').trim();
                    hasDoc = true;
                  } catch (error) {
                    console.warn(`Failed to read DESIGN.md for ${item.name}:`, error);
                  }
                }

                themes.push({
                  name: item.name,
                  displayName,
                  description,
                  hasDoc,
                  hasDesignToken,
                  hasGlobals,
                  hasDesignSpec,
                  hasIndexTsx,
                });
              }
            });
          }

          res.setHeader('Content-Type', 'application/json');
          res.end(JSON.stringify(themes));
        } catch (error: any) {
          console.error('Error loading themes:', error);
          res.statusCode = 500;
          res.end(JSON.stringify({ error: error.message }));
        }
      });
    },
  };
}
