import API_CONFIG from '../config/api';

// Issue interfaces
export interface Issue {
  name: string;
  owner: string;
  creation: string;
  modified: string;
  modified_by: string;
  docstatus: number;
  idx: number;
  naming_series: string;
  subject: string;
  raised_by: string;
  status: string;
  priority?: string;
  issue_type?: string;
  description?: string;
  opening_date: string;
  opening_time: string;
  contact?: string;
  company?: string;
  via_customer_portal: number;
  resolution_by?: string;
  resolution_date?: string;
  first_responded_on?: string;
  resolution_details?: string;
  customer?: string;
  project?: string;
  issue_split_from?: string;
}

export interface CreateIssueData {
  subject: string;
  raised_by?: string;
  status?: string;
  priority?: string;
  issue_type?: string;
  description?: string;
  contact?: string;
  company?: string;
  customer?: string;
  project?: string;
  resolution_details?: string;
  first_responded_on?: string;
  resolution_date?: string;
  resolution_by?: string;
}

export interface IssueListParams {
  filters?: Record<string, any>;
  fields?: string[];
  limit_start?: number;
  limit_page_length?: number;
  order_by?: string;
}

export interface IssueListResponse {
  data: Issue[];
  total_count?: number;
}

class IssueService {
  private baseURL: string;

  constructor() {
    this.baseURL = API_CONFIG.BASE_URL;
  }

  // Get CSRF Token
  private async getCSRFToken(): Promise<string | null> {
    try {
      if (typeof window !== 'undefined' && (window as any).csrf_token) {
        return (window as any).csrf_token;
      }
      return null;
    } catch (error) {
      return null;
    }
  }

  // Get headers with CSRF token
  private async getHeaders(): Promise<Record<string, string>> {
    const headers: Record<string, string> = {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
    };

    const csrfToken = await this.getCSRFToken();
    if (csrfToken) {
      headers['X-Frappe-CSRF-Token'] = csrfToken;
    }

    return headers;
  }

  // Get list of issues
  async getIssues(params: IssueListParams = {}): Promise<IssueListResponse> {
    const {
      filters = {},
      fields = ['name', 'subject', 'raised_by', 'status', 'priority', 'issue_type', 'opening_date', 'company', 'contact', 'creation', 'modified', 'first_responded_on', 'resolution_date', 'resolution_by'],
      limit_start = 0,
      limit_page_length = 20,
      order_by = 'creation desc',
    } = params;

    const queryParams = new URLSearchParams();
    queryParams.append('fields', JSON.stringify(fields));
    queryParams.append('limit_start', limit_start.toString());
    queryParams.append('limit_page_length', limit_page_length.toString());
    queryParams.append('order_by', order_by);

    if (Object.keys(filters).length > 0) {
      const filterArray = Object.entries(filters).map(([key, value]) => [key, '=', value]);
      queryParams.append('filters', JSON.stringify(filterArray));
    }

    const response = await fetch(
      `${this.baseURL}/api/resource/Issue?${queryParams.toString()}`,
      {
        method: 'GET',
        headers: await this.getHeaders(),
        credentials: 'include',
      }
    );

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const result = await response.json();
    return { data: result.data || [] };
  }

  // Get single issue details
  async getIssue(name: string): Promise<Issue> {
    const response = await fetch(
      `${this.baseURL}/api/resource/Issue/${encodeURIComponent(name)}`,
      {
        method: 'GET',
        headers: await this.getHeaders(),
        credentials: 'include',
      }
    );

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const result = await response.json();
    return result.data;
  }

  // Create new issue
  async createIssue(data: CreateIssueData): Promise<Issue> {
    const response = await fetch(
      `${this.baseURL}/api/resource/Issue`,
      {
        method: 'POST',
        headers: await this.getHeaders(),
        credentials: 'include',
        body: JSON.stringify(data),
      }
    );

    if (!response.ok) {
      const errorData = await response.json().catch(() => ({}));
      throw new Error(errorData.message || `HTTP error! status: ${response.status}`);
    }

    const result = await response.json();
    return result.data;
  }

  // Update issue
  async updateIssue(name: string, data: Partial<CreateIssueData>): Promise<Issue> {
    const response = await fetch(
      `${this.baseURL}/api/resource/Issue/${encodeURIComponent(name)}`,
      {
        method: 'PUT',
        headers: await this.getHeaders(),
        credentials: 'include',
        body: JSON.stringify(data),
      }
    );

    if (!response.ok) {
      const errorData = await response.json().catch(() => ({}));
      throw new Error(errorData.message || `HTTP error! status: ${response.status}`);
    }

    const result = await response.json();
    return result.data;
  }

  // Delete issue
  async deleteIssue(name: string): Promise<void> {
    const response = await fetch(
      `${this.baseURL}/api/resource/Issue/${encodeURIComponent(name)}`,
      {
        method: 'DELETE',
        headers: await this.getHeaders(),
        credentials: 'include',
      }
    );

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
  }

  // Get issue count
  async getIssueCount(filters: Record<string, any> = {}): Promise<number> {
    const queryParams = new URLSearchParams();
    queryParams.append('fields', JSON.stringify(['count(name) as count']));

    if (Object.keys(filters).length > 0) {
      const filterArray = Object.entries(filters).map(([key, value]) => [key, '=', value]);
      queryParams.append('filters', JSON.stringify(filterArray));
    }

    const response = await fetch(
      `${this.baseURL}/api/resource/Issue?${queryParams.toString()}`,
      {
        method: 'GET',
        headers: await this.getHeaders(),
        credentials: 'include',
      }
    );

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const result = await response.json();
    return result.data?.[0]?.count || 0;
  }
}

const issueService = new IssueService();
export default issueService;