<template>
  <div class="jmap-config-panel">
    <h3 class="text-h6 mb-4">JMAP Connection Settings</h3>
    <p class="text-body-2 mb-6">Configure how to connect to your JMAP server.</p>

    <!-- Manual Configuration Toggle -->
    <v-switch
      v-model="configureManually"
      label="Configure server manually"
      color="primary"
      class="mb-4"
    />

    <!-- Session URL (Simple Mode) -->
    <template v-if="!configureManually">
      <v-text-field
        v-model="sessionUrl"
        label="JMAP Session URL"
        hint="e.g., https://jmap.example.com/.well-known/jmap"
        persistent-hint
        variant="outlined"
        prepend-inner-icon="mdi-link"
        class="mb-4"
        :rules="[rules.required, rules.url]"
      />
    </template>

    <!-- Manual Configuration Fields -->
    <template v-if="configureManually">
      <v-text-field
        v-model="serviceHost"
        label="Service Address"
        hint="Domain or IP Address"
        persistent-hint
        variant="outlined"
        prepend-inner-icon="mdi-server"
        class="mb-4"
        autocomplete="off"
        autocorrect="off"
        autocapitalize="none"
        :rules="[rules.required]"
      />

      <div class="mb-4">
        <label class="text-subtitle-2 mb-2 d-block">Service Protocol</label>
        <v-btn-toggle
          v-model="serviceProtocol"
          color="primary"
          variant="outlined"
          mandatory
          divided
        >
          <v-btn value="http">http</v-btn>
          <v-btn value="https">https</v-btn>
        </v-btn-toggle>
      </div>

      <v-switch
        v-model="verifyPeer"
        label="Secure Transport Verification (SSL Certificate Verification)"
        color="primary"
        class="mb-4"
        hint="Should always be ON, unless connecting to a service over a secure internal network"
        persistent-hint
      />

      <v-text-field
        v-model="servicePort"
        label="Service Port"
        hint="Leave empty for default. http (80) https (443)"
        persistent-hint
        variant="outlined"
        prepend-inner-icon="mdi-numeric"
        class="mb-4"
        autocomplete="off"
        autocorrect="off"
        autocapitalize="none"
      />

      <v-text-field
        v-model="servicePath"
        label="Service Path"
        hint="Leave empty for default path (/.well-known/jmap)"
        persistent-hint
        variant="outlined"
        prepend-inner-icon="mdi-folder"
        class="mb-4"
        autocomplete="off"
        autocorrect="off"
        autocapitalize="none"
      />
    </template>

    <!-- Advanced Settings -->
    <v-expansion-panels class="mt-4">
      <v-expansion-panel>
        <v-expansion-panel-title>
          <v-icon start>mdi-cog</v-icon>
          Advanced Settings
        </v-expansion-panel-title>
        <v-expansion-panel-text>
          <v-select
            v-model="capabilities"
            :items="jmapCapabilities"
            label="Enabled Capabilities"
            multiple
            chips
            variant="outlined"
            hint="Select which JMAP capabilities to enable"
            persistent-hint
          />

          <v-text-field
            v-model.number="timeout"
            type="number"
            label="Timeout (seconds)"
            variant="outlined"
            class="mt-4"
            hint="Connection timeout in seconds"
            persistent-hint
            :min="5"
            :max="300"
          />

          <v-switch
            v-model="verifyHost"
            label="Verify SSL Hostname"
            color="primary"
            hint="Verify the certificate matches the hostname"
            persistent-hint
          />
        </v-expansion-panel-text>
      </v-expansion-panel>
    </v-expansion-panels>

    <!-- Info Alert -->
    <v-alert
      type="info"
      variant="tonal"
      density="compact"
      class="mt-4"
    >
      <template #prepend>
        <v-icon>mdi-information</v-icon>
      </template>
      <div class="text-caption">
        JMAP is a modern protocol for mail access. Most JMAP servers use
        <code>/.well-known/jmap</code> for autodiscovery.
      </div>
    </v-alert>
  </div>
</template>

<script setup lang="ts">
import { ref, watch, computed } from 'vue'
import type { ServiceLocationUri, ServiceLocation } from '@KTXM/MailManager/types/service'
import type { ProviderConfigPanelProps, ProviderConfigPanelEmits } from '@KTXM/MailManager/types/integration'

const props = defineProps<ProviderConfigPanelProps>()
const emit = defineEmits<ProviderConfigPanelEmits>()

// Helper to build session URL from location
function buildSessionUrl(location?: ServiceLocation): string {
  if (!location || location.type !== 'URI') return ''
  
  const protocol = location.scheme || 'https'
  const host = location.host || ''
  const port = location.port || (protocol === 'https' ? 443 : 80)
  const path = location.path || '/.well-known/jmap'
  
  // Don't include port if it's the default for the protocol
  const portStr = (protocol === 'https' && port === 443) || (protocol === 'http' && port === 80)
    ? ''
    : `:${port}`
  
  return `${protocol}://${host}${portStr}${path}`
}

// Helper to parse session URL into location
function parseSessionUrl(url: string): ServiceLocationUri {
  try {
    const parsed = new URL(url)
    return {
      type: 'URI',
      scheme: parsed.protocol.replace(':', '') as 'http' | 'https',
      host: parsed.hostname,
      port: parsed.port ? parseInt(parsed.port) : (parsed.protocol === 'https:' ? 443 : 80),
      path: parsed.pathname || '/.well-known/jmap',
      verifyPeer: verifyPeer.value,
      verifyHost: verifyHost.value
    }
  } catch {
    return {
      type: 'URI',
      scheme: 'https',
      host: '',
      port: 443,
      path: '/.well-known/jmap',
      verifyPeer: verifyPeer.value,
      verifyHost: verifyHost.value
    }
  }
}

// Helper to extract URI properties safely
function getUriVerifyPeer(location?: ServiceLocation): boolean {
  return (location?.type === 'URI' ? location.verifyPeer : undefined) ?? true
}

function getUriVerifyHost(location?: ServiceLocation): boolean {
  return (location?.type === 'URI' ? location.verifyHost : undefined) ?? true
}

// Manual configuration toggle and fields
const configureManually = ref(false)
const serviceHost = ref('')
const serviceProtocol = ref<'http' | 'https'>('https')
const servicePort = ref('')
const servicePath = ref('')

// Local state - protocol settings only
const sessionUrl = ref(buildSessionUrl(props.modelValue || props.discoveredLocation))
const capabilities = ref<string[]>(['urn:ietf:params:jmap:mail'])
const timeout = ref(30)
const verifyPeer = ref(getUriVerifyPeer(props.modelValue || props.discoveredLocation))
const verifyHost = ref(getUriVerifyHost(props.modelValue || props.discoveredLocation))

// Validation rules
const rules = {
  required: (value: any) => !!value || 'This field is required',
  url: (value: string) => {
    try {
      new URL(value)
      return true
    } catch {
      return 'Please enter a valid URL'
    }
  }
}

// Build location from current state
const currentLocation = computed((): ServiceLocationUri | null => {
  if (configureManually.value) {
    // Build from manual fields
    if (!serviceHost.value) return null
    
    const port = servicePort.value 
      ? parseInt(servicePort.value) 
      : (serviceProtocol.value === 'https' ? 443 : 80)
    
    return {
      type: 'URI',
      scheme: serviceProtocol.value,
      host: serviceHost.value,
      port,
      path: servicePath.value || '/.well-known/jmap',
      verifyPeer: verifyPeer.value,
      verifyHost: verifyHost.value
    }
  } else {
    // Build from session URL
    if (!sessionUrl.value) return null
    return parseSessionUrl(sessionUrl.value)
  }
})

// Validation state
const isValid = computed(() => {
  if (configureManually.value) {
    return !!serviceHost.value
  } else {
    return !!sessionUrl.value && rules.url(sessionUrl.value) === true
  }
})

// Emit location whenever it changes
watch(
  currentLocation,
  (newLocation) => {
    if (newLocation) {
      emit('update:modelValue', newLocation)
    }
  },
  { immediate: true, deep: true }
)

// Emit validation state
watch(
  isValid,
  (valid) => {
    emit('valid', valid)
  },
  { immediate: true }
)

// Update local state when props change
watch(
  () => props.modelValue,
  (newValue) => {
    if (newValue && newValue.type === 'URI') {
      sessionUrl.value = buildSessionUrl(newValue)
      verifyPeer.value = newValue.verifyPeer ?? true
      verifyHost.value = newValue.verifyHost ?? true
    }
  }
)

watch(
  () => props.discoveredLocation,
  (newValue) => {
    if (newValue && newValue.type === 'URI' && !props.modelValue) {
      sessionUrl.value = buildSessionUrl(newValue)
      verifyPeer.value = newValue.verifyPeer ?? true
      verifyHost.value = newValue.verifyHost ?? true
    }
  },
  { immediate: true }
)

const jmapCapabilities = [
  { title: 'Mail', value: 'urn:ietf:params:jmap:mail' },
  { title: 'Contacts', value: 'urn:ietf:params:jmap:contacts' },
  { title: 'Calendars', value: 'urn:ietf:params:jmap:calendars' },
  { title: 'Tasks', value: 'urn:ietf:params:jmap:tasks' },
  { title: 'Notes', value: 'urn:ietf:params:jmap:notes' },
]
</script>

<style scoped>
.jmap-config-panel {
  max-width: 800px;
}

code {
  background-color: rgba(var(--v-theme-surface-variant), 0.3);
  padding: 2px 6px;
  border-radius: 4px;
  font-family: 'Courier New', monospace;
  font-size: 0.9em;
}

.text-h6 {
  font-size: 1.25rem;
  font-weight: 500;
  line-height: 2rem;
  letter-spacing: 0.0125em;
}

.text-subtitle-2 {
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.375rem;
  letter-spacing: 0.00714em;
}

.text-body-2 {
  font-size: 0.875rem;
  font-weight: 400;
  line-height: 1.25rem;
  letter-spacing: 0.0178571429em;
  color: rgba(var(--v-theme-on-surface), 0.7);
}
</style>
