import axios from "axios";
import {
  TemplateResource,
  TemplateResponse,
  ResourceTypeResponse,
  CreateTemplatePayload,
} from "../TemplateConfiguration/types/templateTypes";
import { XSSUploadValidator } from "@/shared/services/validation";
import { presignedAxios } from "@/shared/services/presignedAxios";
import Cookies from "js-cookie";
import { getEnvUrl } from "@/shared/config/env";

const TENANT_ID = "adf98293-41ba-4bda-bdb4-70e30a70c1b7";
const API_URL = getEnvUrl("VITE_RECORD_API_URL", false);

// Create axios instance for template API
const apiInstance = axios.create({
  baseURL: API_URL,
});

// Add authorization interceptor
apiInstance.interceptors.request.use((config) => {
  const token = Cookies.get("auth-token");
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  config.headers["x-tenant-id"] = TENANT_ID;
  return config;
});

const normalizeTemplateItem = (
  item: Record<string, unknown>,
): TemplateResource => {
  return {
    ...item,
    name: (item.name as Record<string, string>) || { am: "", en: "" },
    description: (item.description as Record<string, string>) || {
      am: "",
      en: "",
    },
  } as TemplateResource;
};

export const TemplateService = {
  async getResourceTypes(): Promise<ResourceTypeResponse> {
    const response = await apiInstance.get("/resource_types");
    return response.data;
  },

  async getTemplates(
    params?: Record<string, unknown>,
  ): Promise<TemplateResponse> {
    const { resourceTypeId, search, ...otherParams } = params || {};

    // resourceTypeId is required for the API endpoint
    if (!resourceTypeId) {
      return {
        count: 0,
        items: [],
      };
    }

    const response = await apiInstance.get(
      `/resources/list-with-presigned/${resourceTypeId}`,
      { params: otherParams },
    );

    let items = (response.data.items || []).map(normalizeTemplateItem);

    // Client-side filtering by search
    if (search && typeof search === "string") {
      const searchLower = search.toLowerCase();
      items = items.filter(
        (item: TemplateResource) =>
          item.name?.en?.toLowerCase().includes(searchLower) ||
          item.name?.am?.toLowerCase().includes(searchLower) ||
          item.description?.en?.toLowerCase().includes(searchLower) ||
          item.description?.am?.toLowerCase().includes(searchLower),
      );
    }

    return {
      count: items.length,
      items,
    };
  },

  async getTemplate(id: string): Promise<TemplateResource> {
    const response = await apiInstance.get(
      `/resources/with-presigned?id=${id}`,
    );
    return normalizeTemplateItem(response.data);
  },

  async getTemplateWithPresigned(
    resourceTypeId: string,
    templateId: string,
  ): Promise<TemplateResource> {
    try {
      const response = await apiInstance.get(
        `/resources/list-with-presigned/${resourceTypeId}`,
      );
      const items = (response.data.items || []).map(normalizeTemplateItem);
      const template = items.find(
        (item: TemplateResource) => item.id === templateId,
      );
      if (!template) {
        throw new Error("Template not found");
      }
      return template;
    } catch (error: unknown) {
      const axiosError = error as Record<string, unknown>;
      // If the file hasn't been uploaded successfully, try to get basic template info
      if ((axiosError.response as Record<string, unknown>)?.status === 400) {
        try {
          const response = await apiInstance.get(
            `/resources/with-presigned?id=${templateId}`,
          );
          return normalizeTemplateItem(response.data);
        } catch {
          throw error;
        }
      }
      throw error;
    }
  },

  async createTemplate(data: CreateTemplatePayload): Promise<TemplateResource> {
    const response = await apiInstance.post("/resources", data);
    return normalizeTemplateItem(response.data);
  },

  async updateTemplate(
    id: string,
    data: Partial<CreateTemplatePayload>,
  ): Promise<TemplateResource> {
    const response = await apiInstance.put(`/resources/${id}`, data);
    return normalizeTemplateItem(response.data);
  },

  async deleteTemplate(id: string): Promise<void> {
    await apiInstance.delete(`/resources/${id}`);
  },

  async uploadFile(file: File, uploadUrl?: string) {
    if (!uploadUrl) {
      console.warn("No upload URL provided, skipping file upload");
      return null;
    }

    const validationResult = await XSSUploadValidator.validateFileForUpload(
      file,
      {
        allowedMimeTypes: [
          "image/png",
          "image/jpeg",
          "image/gif",
          "image/webp",
          "application/pdf",
        ],
        allowedExtensions: [".png", ".jpg", ".jpeg", ".gif", ".webp", ".pdf"],
        maxSizeMB: 50,
        uploadContext: "signature",
      },
    );

    if (!validationResult.isValid) {
      throw new Error(
        validationResult.clientValidation.fileName?.error ||
          validationResult.clientValidation.extension?.error ||
          validationResult.clientValidation.mimeType?.error ||
          validationResult.clientValidation.size?.error ||
          "File validation failed",
      );
    }
    return presignedAxios.put(uploadUrl, file, {
      headers: {
        "Content-Type": file.type,
      },
    });
  },

  async updateUploadStatus(
    id: string,
    uploadedSuccessfully: boolean,
  ): Promise<void> {
    await apiInstance.put(`/resources/change-status/${id}`, {
      isCurrent: uploadedSuccessfully,
    });
  },
};
