import { type ActionFunctionArgs } from '@remix-run/node';
import { get1PanelConnectionSettings, save1PanelConnectionSettings } from '~/lib/.server/connectionSettings';
import { createOrUpdateDeployment, getLatestDeployment } from '~/lib/.server/deployment';
import { createScopedLogger } from '~/lib/.server/logger';
import {
  createWebsite,
  getWebsite,
  getWebsiteByPrimaryDomain,
  type UploadFileContent,
  uploadFiles,
} from '~/routes/api.1panel.$action/1panel.server';
import type { _1PanelWebsite, _1PanelWebsiteInfo } from '~/types/1panel';
import { DeploymentPlatformEnum, DeploymentStatusEnum } from '~/types/deployment';
import { errorResponse, successResponse } from '~/utils/api-response';

interface DeployRequestBody {
  websiteId: number;
  files: Record<string, string>;
  chatId: string;
  serverUrl?: string;
  apiKey?: string;
  websiteDomain?: string;
  protocol?: string;
}

export type HandleDeployArgs = ActionFunctionArgs & {
  userId: string;
};

const logger = createScopedLogger('api.1panel.deploy');

export async function handleDeploy({ request, userId }: HandleDeployArgs) {
  try {
    const {
      websiteId,
      files,
      chatId,
      serverUrl: requestServerUrl,
      apiKey: requestApiKey,
      websiteDomain,
      protocol,
    } = (await request.json()) as DeployRequestBody;

    // 从用户设置中获取连接信息
    let connectionSettings = await get1PanelConnectionSettings(userId);

    // 如果请求体中提供了连接信息，优先使用请求体中的信息，并更新用户设置
    if (requestServerUrl && requestApiKey) {
      connectionSettings = {
        serverUrl: requestServerUrl,
        apiKey: requestApiKey,
      };

      // 更新用户设置
      await save1PanelConnectionSettings(userId, requestServerUrl, requestApiKey);
    }

    // 如果没有连接信息，返回错误
    if (!connectionSettings) {
      logger.warn('未配置1Panel连接信息');
      return errorResponse(401, '未配置1Panel连接信息，请先设置服务器地址和API密钥');
    }

    const { serverUrl, apiKey } = connectionSettings;

    logger.debug('action => request', { websiteId, files, chatId, serverUrl, websiteDomain, protocol });

    const existingDeployment = await getLatestDeployment(userId, chatId, DeploymentPlatformEnum._1PANEL);
    let targetWebsiteId;
    if (websiteId) {
      targetWebsiteId = websiteId;
    } else if (existingDeployment?.deploymentId) {
      targetWebsiteId = parseInt(existingDeployment.deploymentId);
    } else {
      targetWebsiteId = undefined;
    }

    let websiteInfo: _1PanelWebsiteInfo | undefined;
    if (targetWebsiteId) {
      const websiteResponse = await getWebsite({
        serverUrl,
        apiKey,
        siteId: targetWebsiteId,
      });

      logger.debug('action => getWebsite', JSON.stringify(websiteResponse));

      if (websiteResponse.data) {
        const existingWebsite = websiteResponse.data as _1PanelWebsite;
        websiteInfo = {
          id: existingWebsite.id,
          domain: existingWebsite.primaryDomain,
          url: `${existingWebsite.protocol.toLowerCase()}://${existingWebsite.primaryDomain}`,
          alias: existingWebsite.alias,
          sitePath: existingWebsite.sitePath,
          chatId,
        };
      }
    }

    if (!websiteInfo) {
      // If no websiteId provided, create a new website
      const alias = `upage-${chatId}-${Date.now()}`;
      const createWebsiteResponse = await createWebsite({
        serverUrl,
        apiKey,
        alias,
        primaryDomain: websiteDomain,
        proxyProtocol: `${protocol || 'http'}://`,
        isSSL: protocol === 'https',
      });

      logger.debug('action => createWebsite', JSON.stringify(createWebsiteResponse));

      if (createWebsiteResponse.code !== 200) {
        logger.warn('无法创建网站', JSON.stringify(createWebsiteResponse));
        return errorResponse(400, `无法创建网站: ${createWebsiteResponse.data?.message || 'Unknown error'}`);
      }

      const { domain } = createWebsiteResponse.data as { domain: string };

      const webSiteInfo = await getWebsiteByPrimaryDomain(serverUrl, apiKey, domain);
      if (webSiteInfo.code !== 200) {
        logger.warn('无法获取网站信息', JSON.stringify(webSiteInfo));
        return errorResponse(400, '无法获取网站信息');
      }
      if (webSiteInfo.data.items == null) {
        logger.warn('获取网站失败，请检查 1Panel 日志', JSON.stringify(webSiteInfo));
        return errorResponse(400, '获取网站失败，请检查 1Panel 日志');
      }

      const newWebsite = webSiteInfo.data.items.find((item) => item.alias === alias);
      if (!newWebsite) {
        logger.warn('无法获取网站信息', JSON.stringify(newWebsite));
        return errorResponse(400, '无法获取网站信息');
      }

      targetWebsiteId = newWebsite.id;
      websiteInfo = {
        id: newWebsite.id,
        domain: newWebsite.primaryDomain,
        sitePath: newWebsite.sitePath,
        alias: newWebsite.alias,
        url: `${newWebsite.protocol.toLowerCase()}://${newWebsite.primaryDomain}`,
        chatId,
      };
    }

    logger.info('创建网站成功 => ', websiteInfo.id, websiteInfo.domain, websiteInfo.url);

    if (!websiteInfo) {
      return errorResponse(400, '无法创建网站');
    }

    const deploymentFiles: UploadFileContent[] = [];
    for (const [filePath, content] of Object.entries(files)) {
      const lastSlashIndex = filePath.lastIndexOf('/');
      const folderPath = lastSlashIndex !== -1 ? filePath.substring(0, lastSlashIndex + 1) : '';
      const fileName = lastSlashIndex !== -1 ? filePath.substring(lastSlashIndex + 1) : filePath;
      // 获取 filename
      deploymentFiles.push({
        path: `${websiteInfo.sitePath}/index/${folderPath}`,
        fileName,
        data: content,
      });
    }

    logger.debug('action => uploadFiles', JSON.stringify(deploymentFiles));

    try {
      await uploadFiles({
        serverUrl,
        apiKey,
        version: 'v2',
        files: deploymentFiles,
      });
    } catch (error) {
      logger.warn('action => uploadFiles error', JSON.stringify(error));
      const errorMessage = error instanceof Error ? error.message : String(error);
      return errorResponse(400, `无法上传文件: ${errorMessage}`);
    }

    try {
      await createOrUpdateDeployment({
        userId,
        chatId,
        platform: DeploymentPlatformEnum._1PANEL,
        deploymentId: String(websiteInfo.id),
        url: websiteInfo.url,
        status: DeploymentStatusEnum.SUCCESS,
        metadata: {
          domain: websiteInfo.domain,
          alias: websiteInfo.alias,
          sitePath: websiteInfo.sitePath,
          serverUrl,
        },
      });
      logger.info(`为用户 ${userId} 创建了 1Panel 部署记录`);
    } catch (error) {
      logger.error('创建部署记录失败:', error);
    }

    return successResponse(
      {
        deploy: {
          id: websiteInfo.id,
          domain: websiteInfo.domain,
          url: websiteInfo.url,
        },
      },
      '部署成功',
    );
  } catch (error) {
    console.error('1Panel deploy error:', error);
    return errorResponse(500, '部署到 1Panel 失败');
  }
}
