import { appendClientIdHeader } from '../../../../app/main/clientIdentity';
import { getRegisteredAccessToken } from '../../../../app/main/tokenAccess';

const WORK_SERVER_TIMEOUT_MS = 10000;

export type TestAppMaintenanceRequestRow = {
  id: number;
  requestNo: string;
  lineCode: string;
  equipmentName: string;
  issueType: string;
  priority: '긴급' | '높음' | '보통' | '낮음';
  requesterName: string;
  assigneeName: string;
  status: '접수' | '배정완료' | '조치중' | '부품대기' | '완료';
  requestedAt: string;
  lastActionAt: string;
  isDirty?: boolean;
};

export type TestAppMaintenanceRequestFilters = {
  keyword: string;
  lineCode: string;
  priority: string;
  status: string;
  requestedFrom: string;
  requestedTo: string;
};

export type TestAppMaintenanceRequestListResponse = {
  ok: true;
  items: TestAppMaintenanceRequestRow[];
  page: number;
  pageSize: number;
  total: number;
  hasNext: boolean;
  filters: {
    keyword: string;
    lineCode: string;
    priority: string;
    status: string;
    requestedFrom: string | null;
    requestedTo: string | null;
  };
};

export type TestAppLegacyStatus = '대기' | '진행' | '완료' | '점검필요';

export type TestAppGridRow = {
  id: number;
  pressureWindow: string;
  status: TestAppLegacyStatus;
  measuredValue: number;
  createdAt: string;
  updatedAt: string;
  isDirty?: boolean;
};

export type TestAppFilters = {
  pressureWindow: string;
  status: string;
  minMeasuredValue: string;
  maxMeasuredValue: string;
  dateFrom: string;
  dateTo: string;
};

export type TestAppListResponse = {
  ok: true;
  items: TestAppGridRow[];
  pagination: {
    page: number;
    pageSize: number;
    total: number;
    totalPages: number;
  };
  filters: {
    pressureWindow: string;
    status: string;
    minMeasuredValue: number | null;
    maxMeasuredValue: number | null;
    dateFrom: string | null;
    dateTo: string | null;
  };
};

function resolveWorkServerBaseUrl() {
  if (import.meta.env.VITE_WORK_SERVER_URL) {
    return import.meta.env.VITE_WORK_SERVER_URL;
  }

  return '/api';
}

const WORK_SERVER_BASE_URL = resolveWorkServerBaseUrl();

async function request<T>(path: string, init?: RequestInit) {
  const headers = appendClientIdHeader(init?.headers);
  const controller = new AbortController();
  const timeoutId = window.setTimeout(() => controller.abort(), WORK_SERVER_TIMEOUT_MS);

  if (init?.body && !headers.has('Content-Type')) {
    headers.set('Content-Type', 'application/json');
  }

  const token = getRegisteredAccessToken();
  if (token && !headers.has('X-Access-Token')) {
    headers.set('X-Access-Token', token);
  }

  try {
    const response = await fetch(`${WORK_SERVER_BASE_URL}${path}`, {
      ...init,
      headers,
      signal: controller.signal,
      cache: init?.cache ?? 'no-store',
    });

    if (!response.ok) {
      const text = await response.text();

      try {
        const payload = JSON.parse(text) as { message?: string };
        throw new Error(payload.message || 'Test App 요청에 실패했습니다.');
      } catch {
        throw new Error(text || 'Test App 요청에 실패했습니다.');
      }
    }

    return response.json() as Promise<T>;
  } finally {
    window.clearTimeout(timeoutId);
  }
}

function toLegacyRow(item: TestAppMaintenanceRequestRow): TestAppGridRow {
  return {
    pressureWindow: `${item.equipmentName} / ${item.requestNo}`,
    status:
      item.status === '접수'
        ? '대기'
        : item.status === '배정완료'
          ? '점검필요'
          : item.status === '조치중'
            ? '진행'
            : '완료',
    measuredValue:
      item.priority === '긴급'
        ? 95
        : item.priority === '높음'
          ? 78
          : item.priority === '보통'
            ? 54
            : 28,
    createdAt: item.requestedAt,
    updatedAt: item.lastActionAt,
    id: item.id,
  };
}

export async function fetchTestAppMaintenanceRequests(
  page: number,
  pageSize: number,
  filters: TestAppMaintenanceRequestFilters,
) {
  const params = new URLSearchParams({
    page: String(page),
    pageSize: String(pageSize),
  });

  if (filters.keyword.trim()) {
    params.set('keyword', filters.keyword.trim());
  }

  if (filters.lineCode && filters.lineCode !== '전체') {
    params.set('lineCode', filters.lineCode);
  }

  if (filters.priority && filters.priority !== '전체') {
    params.set('priority', filters.priority);
  }

  if (filters.status && filters.status !== '전체') {
    params.set('status', filters.status);
  }

  if (filters.requestedFrom) {
    params.set('requestedFrom', filters.requestedFrom);
  }

  if (filters.requestedTo) {
    params.set('requestedTo', filters.requestedTo);
  }

  return request<TestAppMaintenanceRequestListResponse>(`/test-app/maintenance-requests?${params.toString()}`);
}

export async function saveTestAppMaintenanceRequests(items: TestAppMaintenanceRequestRow[]) {
  return request<{ ok: true; count: number; items: TestAppMaintenanceRequestRow[] }>('/test-app/maintenance-requests', {
    method: 'PUT',
    body: JSON.stringify({
      items: items.map((item) => ({
        id: item.id,
        priority: item.priority,
        status: item.status,
        assigneeName: item.assigneeName,
      })),
    }),
  });
}

export async function deleteTestAppMaintenanceRequest(id: number) {
  return request<{ ok: true; deletedId: number; item: TestAppMaintenanceRequestRow }>(`/test-app/maintenance-requests/${id}`, {
    method: 'DELETE',
  });
}

export async function fetchTestAppMeasurements(page: number, pageSize: number, filters: TestAppFilters) {
  const response = await fetchTestAppMaintenanceRequests(page, pageSize, {
    keyword: filters.pressureWindow,
    lineCode: '전체',
    priority: '전체',
    status: filters.status,
    requestedFrom: filters.dateFrom,
    requestedTo: filters.dateTo,
  });

  return {
    ok: true,
    items: response.items.map(toLegacyRow),
    pagination: {
      page: response.page,
      pageSize: response.pageSize,
      total: response.total,
      totalPages: Math.max(1, Math.ceil(response.total / response.pageSize)),
    },
    filters: {
      pressureWindow: response.filters.keyword,
      status: response.filters.status,
      minMeasuredValue: null,
      maxMeasuredValue: null,
      dateFrom: response.filters.requestedFrom,
      dateTo: response.filters.requestedTo,
    },
  } satisfies TestAppListResponse;
}

export async function saveTestAppMeasurements(items: TestAppGridRow[]) {
  return request<{ ok: true; count: number; items: TestAppMaintenanceRequestRow[] }>('/test-app/maintenance-requests', {
    method: 'PUT',
    body: JSON.stringify({
      items: items.map((item) => ({
        id: item.id,
        priority: item.measuredValue >= 85 ? '긴급' : item.measuredValue >= 65 ? '높음' : item.measuredValue >= 40 ? '보통' : '낮음',
        status: item.status === '대기' ? '접수' : item.status === '점검필요' ? '배정완료' : item.status === '진행' ? '조치중' : '완료',
        assigneeName: item.status === '대기' ? '' : '호환저장',
      })),
    }),
  });
}
