/**
 * Availability Service
 *
 * Serviço para gerenciamento de disponibilidade dos médicos
 */

import { apiClient } from "../api/client";
import {
  DoctorAvailability,
  ListAvailabilityFilters,
  CreateAvailabilityInput,
  UpdateAvailabilityInput,
  DoctorException,
  CreateExceptionInput,
} from "./types";

class AvailabilityService {
  private readonly basePath = "/doctor_availability";
  private readonly exceptionsPath = "/doctor_exceptions";

  /**
   * Lista as disponibilidades dos médicos via Supabase REST API
   */
  async list(filters?: ListAvailabilityFilters): Promise<DoctorAvailability[]> {
    const params: Record<string, string> = {};

    if (filters?.doctor_id) {
      params.doctor_id = `eq.${filters.doctor_id}`;
    }
    if (filters?.weekday !== undefined) {
      params.weekday = `eq.${filters.weekday}`;
    }
    if (filters?.active !== undefined) {
      params.active = `eq.${filters.active}`;
    }
    if (filters?.appointment_type) {
      params.appointment_type = `eq.${filters.appointment_type}`;
    }

    console.log("[AvailabilityService] Listando disponibilidades:", {
      filters,
      params,
      url: this.basePath,
    });

    const response = await apiClient.get<any[]>(this.basePath, {
      params,
    });

    console.log("[AvailabilityService] Resposta:", {
      count: response.data?.length || 0,
      isArray: Array.isArray(response.data),
    });

    // DEBUG: Buscar TODAS disponibilidades para debug
    if (filters?.doctor_id && response.data?.length === 0) {
      console.log(
        "[AvailabilityService] 🔍 Buscando TODAS disponibilidades para debug..."
      );
      const allResponse = await apiClient.get<any[]>(this.basePath, {});
      console.log(
        "[AvailabilityService] 📊 Total de disponibilidades no banco:",
        allResponse.data?.length
      );
      if (allResponse.data?.length > 0) {
        console.log(
          "[AvailabilityService] 📋 Primeiras 3 disponibilidades:",
          allResponse.data.slice(0, 3).map((d) => ({
            id: d.id,
            doctor_id: d.doctor_id,
            weekday: d.weekday,
            active: d.active,
          }))
        );
        console.log(
          "[AvailabilityService] ⚠️ doctor_id procurado:",
          filters.doctor_id
        );
        console.log(
          "[AvailabilityService] 🔍 IDs de médicos únicos no banco:",
          [...new Set(allResponse.data.map((d) => d.doctor_id))]
        );
      }
    }

    // Converter weekday de string para número (compatibilidade com banco antigo)
    const convertedData: DoctorAvailability[] = Array.isArray(response.data)
      ? response.data.map((item) => {
          const weekdayMap: Record<string, number> = {
            sunday: 0,
            monday: 1,
            tuesday: 2,
            wednesday: 3,
            thursday: 4,
            friday: 5,
            saturday: 6,
          };

          return {
            ...item,
            weekday:
              typeof item.weekday === "string"
                ? weekdayMap[item.weekday.toLowerCase()]
                : item.weekday,
          };
        })
      : [];

    if (convertedData.length > 0) {
      console.log(
        "[AvailabilityService] ✅ Convertido:",
        convertedData.length,
        "registros"
      );
      console.log(
        "[AvailabilityService] Primeiro item convertido:",
        JSON.stringify(convertedData[0], null, 2)
      );
    }

    return convertedData;
  }

  /**
   * Cria uma nova configuração de disponibilidade
   */
  async create(data: CreateAvailabilityInput): Promise<DoctorAvailability> {
    console.log("[AvailabilityService] Criando disponibilidade:", {
      data,
      url: this.basePath,
    });

    const response = await apiClient.post<DoctorAvailability[]>(
      this.basePath,
      data,
      {
        headers: {
          Prefer: "return=representation",
        },
      }
    );

    console.log("[AvailabilityService] Resposta da criação:", response.data);

    return Array.isArray(response.data) ? response.data[0] : response.data;
  }

  /**
   * Atualiza uma configuração de disponibilidade
   */
  async update(
    id: string,
    data: UpdateAvailabilityInput
  ): Promise<DoctorAvailability> {
    console.log("[AvailabilityService] Atualizando disponibilidade:", {
      id,
      data,
      url: `${this.basePath}?id=eq.${id}`,
    });

    const response = await apiClient.patch<DoctorAvailability[]>(
      `${this.basePath}?id=eq.${id}`,
      data,
      {
        headers: {
          Prefer: "return=representation",
        },
      }
    );

    console.log(
      "[AvailabilityService] Resposta da atualização:",
      response.data
    );

    return Array.isArray(response.data) ? response.data[0] : response.data;
  }

  /**
   * Remove uma configuração de disponibilidade
   */
  async delete(id: string): Promise<void> {
    await apiClient.delete(`${this.basePath}?id=eq.${id}`);
  }

  /**
   * Lista exceções de agenda (bloqueios e disponibilidades extras)
   */
  async listExceptions(filters?: {
    doctor_id?: string;
    date?: string;
    kind?: "bloqueio" | "disponibilidade_extra";
  }): Promise<DoctorException[]> {
    const params: Record<string, string> = {};

    if (filters?.doctor_id) {
      params.doctor_id = `eq.${filters.doctor_id}`;
    }
    if (filters?.date) {
      params.date = `eq.${filters.date}`;
    }
    if (filters?.kind) {
      params.kind = `eq.${filters.kind}`;
    }

    const response = await apiClient.get<DoctorException[]>(
      this.exceptionsPath,
      { params }
    );
    return response.data;
  }

  /**
   * Cria uma exceção de agenda
   */
  async createException(data: CreateExceptionInput): Promise<DoctorException> {
    const response = await apiClient.post<DoctorException[]>(
      this.exceptionsPath,
      data,
      {
        headers: {
          Prefer: "return=representation",
        },
      }
    );
    return Array.isArray(response.data) ? response.data[0] : response.data;
  }

  /**
   * Remove uma exceção de agenda
   */
  async deleteException(id: string): Promise<void> {
    await apiClient.delete(`${this.exceptionsPath}?id=eq.${id}`);
  }
}

export const availabilityService = new AvailabilityService();
