"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import { reportApi } from "@/lib/api/reportApi";
import { ReportDetail, ReportPage, ReportQuery, WatermarkConfig } from "@/types/report";

export interface QueryResult {
  queryId: string;
  fields: string[];
  rows: Record<string, unknown>[];
}

/**
 * 리포트 데이터 로딩 + 쿼리 실행 훅
 *
 * ReportListPreviewModal의 데이터 로딩 로직을 추출하여
 * 모달/인라인 어디서든 재사용 가능하도록 분리.
 */
export function useReportRenderer(
  reportId: string | null,
  contextParams?: Record<string, unknown>,
) {
  const [detail, setDetail] = useState<ReportDetail | null>(null);
  const [queryResults, setQueryResults] = useState<QueryResult[]>([]);
  const [isLoading, setIsLoading] = useState(false);

  const getQueryResult = useCallback(
    (queryId: string): QueryResult | null => {
      return queryResults.find((r) => r.queryId === queryId) || null;
    },
    [queryResults],
  );

  useEffect(() => {
    if (!reportId) {
      setDetail(null);
      setQueryResults([]);
      return;
    }

    let cancelled = false;
    setIsLoading(true);

    (async () => {
      try {
        const res = await reportApi.getReportById(reportId);
        if (cancelled || !res.success) return;

        setDetail(res.data);

        // 쿼리 자동 실행
        const queries: ReportQuery[] = res.data.queries ?? [];
        if (queries.length === 0) return;

        // contextParams에서 키 기반으로 매핑 ($1, $2 등 키를 우선 매칭)
        const buildParams = (parameters: string[]): Record<string, unknown> => {
          const result: Record<string, unknown> = {};
          parameters.forEach((param) => {
            result[param] = contextParams?.[param] ?? null;
          });
          return result;
        };

        const results: QueryResult[] = [];
        for (const q of queries) {
          try {
            const params = buildParams(q.parameters ?? []);
            const execRes = await reportApi.executeQuery(
              reportId,
              q.query_id,
              params,
              undefined, // sql_query를 보내지 않고 서버 저장 쿼리 사용
              q.external_connection_id,
            );
            if (execRes.success && execRes.data) {
              results.push({
                queryId: q.query_id,
                fields: execRes.data.fields,
                rows: execRes.data.rows,
              });
            }
          } catch {
            // 개별 쿼리 실패는 무시
          }
        }

        if (!cancelled) setQueryResults(results);
      } catch {
        if (!cancelled) {
          setDetail(null);
          setQueryResults([]);
        }
      } finally {
        if (!cancelled) setIsLoading(false);
      }
    })();

    return () => {
      cancelled = true;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [reportId, JSON.stringify(contextParams)]);

  const { pages, watermark } = useMemo(() => {
    const empty = { pages: [] as ReportPage[], watermark: undefined as WatermarkConfig | undefined };
    if (!detail?.layout) return empty;

    const layout = detail.layout as unknown as Record<string, unknown>;

    let config: Record<string, unknown> | null = null;

    let raw: unknown = layout.components;

    while (typeof raw === "string") {
      try {
        raw = JSON.parse(raw);
      } catch {
        break;
      }
    }

    if (raw && typeof raw === "object" && !Array.isArray(raw)) {
      config = raw as Record<string, unknown>;
    }

    if (!config && Array.isArray(layout.pages)) {
      config = layout;
    }

    if (!config) return empty;

    const foundPages = Array.isArray(config.pages) ? (config.pages as ReportPage[]) : [];
    const foundWatermark = config.watermark as WatermarkConfig | undefined;

    return { pages: foundPages, watermark: foundWatermark };
  }, [detail?.layout]);

  return {
    detail,
    pages,
    watermark,
    queryResults,
    getQueryResult,
    isLoading,
  };
}
