'use client';

import type { LogChannelMapping, LogEventTypeDashboard, LoggingConfigDashboard } from '@nexumi/shared';
import { Plus, Trash2 } from 'lucide-react';
import { useId } from 'react';
import { FieldAnchor } from '@/components/layout/field-anchor';
import { useTranslations } from '@/components/locale-provider';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Switch } from '@/components/ui/switch';
import { Textarea } from '@/components/ui/textarea';
import type { SettingsSaveResult } from '@/components/settings/settings-form';
import { SettingsForm } from '@/components/settings/settings-form';

const LOG_EVENT_TYPES: LogEventTypeDashboard[] = [
  'MESSAGE_EDIT',
  'MESSAGE_DELETE',
  'MESSAGE_BULK_DELETE',
  'MEMBER_JOIN',
  'MEMBER_LEAVE',
  'MEMBER_BAN',
  'MEMBER_UNBAN',
  'MEMBER_UPDATE',
  'CHANNEL_CREATE',
  'CHANNEL_DELETE',
  'CHANNEL_UPDATE',
  'VOICE_JOIN',
  'VOICE_LEAVE',
  'VOICE_MOVE',
  'INVITE_CREATE',
  'EMOJI_CREATE',
  'EMOJI_UPDATE',
  'EMOJI_DELETE',
  'STICKER_CREATE',
  'STICKER_UPDATE',
  'STICKER_DELETE',
  'THREAD_CREATE',
  'THREAD_UPDATE',
  'THREAD_DELETE',
  'GUILD_UPDATE',
  'MOD_ACTION'
];

interface LocalLogChannel extends LogChannelMapping {
  clientKey: string;
}

interface LocalLoggingValue {
  enabled: boolean;
  ignoreBots: boolean;
  ignoredChannelIdsText: string;
  ignoredRoleIdsText: string;
  retentionDays: number;
  logChannels: LocalLogChannel[];
}

function toCsv(ids: string[]): string {
  return ids.join(', ');
}

function fromCsv(text: string): string[] {
  return text
    .split(',')
    .map((entry) => entry.trim())
    .filter((entry) => entry.length > 0);
}

function toLocal(config: LoggingConfigDashboard): LocalLoggingValue {
  return {
    enabled: config.enabled,
    ignoreBots: config.ignoreBots,
    ignoredChannelIdsText: toCsv(config.ignoredChannelIds),
    ignoredRoleIdsText: toCsv(config.ignoredRoleIds),
    retentionDays: config.retentionDays,
    logChannels: config.logChannels.map((mapping, index) => ({ ...mapping, clientKey: `${mapping.eventType}-${index}` }))
  };
}

function toRemote(value: LocalLoggingValue): LoggingConfigDashboard {
  return {
    enabled: value.enabled,
    ignoreBots: value.ignoreBots,
    ignoredChannelIds: fromCsv(value.ignoredChannelIdsText),
    ignoredRoleIds: fromCsv(value.ignoredRoleIdsText),
    retentionDays: value.retentionDays,
    logChannels: value.logChannels.map(({ clientKey: _clientKey, ...rest }) => rest)
  };
}

async function saveLogging(guildId: string, value: LocalLoggingValue): Promise<SettingsSaveResult> {
  try {
    const response = await fetch(`/api/guilds/${guildId}/logging`, {
      method: 'PATCH',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(toRemote(value))
    });
    if (!response.ok) {
      const body = (await response.json().catch(() => null)) as { error?: string } | null;
      return { ok: false, error: body?.error ?? `Request failed with status ${response.status}` };
    }
    return { ok: true };
  } catch {
    return { ok: false, error: 'Network error' };
  }
}

interface LoggingFormProps {
  guildId: string;
  initialValue: LoggingConfigDashboard;
}

export function LoggingForm({ guildId, initialValue }: LoggingFormProps) {
  const t = useTranslations();
  const ignoredChannelsId = useId();
  const ignoredRolesId = useId();

  return (
    <SettingsForm<LocalLoggingValue>
      initialValue={toLocal(initialValue)}
      onSave={(value) => saveLogging(guildId, value)}
    >
      {({ value, setValue }) => (
        <div className="space-y-6">
          <Card>
            <CardHeader>
              <CardTitle>{t('modulePages.logging.title')}</CardTitle>
              <CardDescription>{t('modulePages.logging.description')}</CardDescription>
            </CardHeader>
            <CardContent className="space-y-4">
              <FieldAnchor id="field-logging-enabled">
              <div className="flex items-center justify-between rounded-md border border-border p-4">
                <Label>{t('modulePages.logging.enabledLabel')}</Label>
                <Switch
                  checked={value.enabled}
                  onCheckedChange={(checked) => setValue((prev) => ({ ...prev, enabled: checked }))}
                />
              </div>
              </FieldAnchor>
              <FieldAnchor id="field-logging-ignore-bots">
              <div className="flex items-center justify-between rounded-md border border-border p-4">
                <Label>{t('modulePages.logging.ignoreBotsLabel')}</Label>
                <Switch
                  checked={value.ignoreBots}
                  onCheckedChange={(checked) => setValue((prev) => ({ ...prev, ignoreBots: checked }))}
                />
              </div>
              </FieldAnchor>
              <FieldAnchor id="field-logging-ignored-channels">
              <div className="space-y-2">
                <Label htmlFor={ignoredChannelsId}>{t('modulePages.logging.ignoredChannelsLabel')}</Label>
                <Textarea
                  id={ignoredChannelsId}
                  value={value.ignoredChannelIdsText}
                  onChange={(event) => setValue((prev) => ({ ...prev, ignoredChannelIdsText: event.target.value }))}
                  placeholder={t('modulePages.logging.idsPlaceholder')}
                />
                <p className="text-xs text-muted-foreground">{t('modulePages.logging.idsHint')}</p>
              </div>
              </FieldAnchor>
              <FieldAnchor id="field-logging-ignored-roles">
              <div className="space-y-2">
                <Label htmlFor={ignoredRolesId}>{t('modulePages.logging.ignoredRolesLabel')}</Label>
                <Textarea
                  id={ignoredRolesId}
                  value={value.ignoredRoleIdsText}
                  onChange={(event) => setValue((prev) => ({ ...prev, ignoredRoleIdsText: event.target.value }))}
                  placeholder={t('modulePages.logging.idsPlaceholder')}
                />
                <p className="text-xs text-muted-foreground">{t('modulePages.logging.idsHint')}</p>
              </div>
              </FieldAnchor>
              <FieldAnchor id="field-logging-retention">
              <div className="space-y-2">
                <Label htmlFor="logging-retention">{t('modulePages.logging.retentionLabel')}</Label>
                <Input
                  id="logging-retention"
                  type="number"
                  min={0}
                  max={3650}
                  className="w-40"
                  value={value.retentionDays}
                  onChange={(event) =>
                    setValue((prev) => ({ ...prev, retentionDays: Number(event.target.value) || 0 }))
                  }
                />
                <p className="text-xs text-muted-foreground">{t('modulePages.logging.retentionHint')}</p>
              </div>
              </FieldAnchor>
            </CardContent>
          </Card>

          <FieldAnchor id="field-logging-channels">
          <Card>
            <CardHeader>
              <CardTitle>{t('modulePages.logging.channelsTitle')}</CardTitle>
              <CardDescription>{t('modulePages.logging.channelsDescription')}</CardDescription>
            </CardHeader>
            <CardContent className="space-y-3">
              {value.logChannels.length === 0 && (
                <p className="text-sm text-muted-foreground">{t('modulePages.logging.channelsEmpty')}</p>
              )}
              {value.logChannels.map((mapping) => (
                <div key={mapping.clientKey} className="flex flex-wrap items-end gap-3 rounded-md border border-border p-3">
                  <div className="space-y-2">
                    <Label>{t('modulePages.logging.eventType')}</Label>
                    <Select
                      value={mapping.eventType}
                      onValueChange={(eventType) =>
                        setValue((prev) => ({
                          ...prev,
                          logChannels: prev.logChannels.map((entry) =>
                            entry.clientKey === mapping.clientKey
                              ? { ...entry, eventType: eventType as LogEventTypeDashboard }
                              : entry
                          )
                        }))
                      }
                    >
                      <SelectTrigger className="w-56">
                        <SelectValue />
                      </SelectTrigger>
                      <SelectContent>
                        {LOG_EVENT_TYPES.map((eventType) => (
                          <SelectItem key={eventType} value={eventType}>
                            {eventType}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                  <div className="flex-1 space-y-2">
                    <Label>{t('modulePages.logging.channelId')}</Label>
                    <Input
                      value={mapping.channelId}
                      onChange={(event) =>
                        setValue((prev) => ({
                          ...prev,
                          logChannels: prev.logChannels.map((entry) =>
                            entry.clientKey === mapping.clientKey ? { ...entry, channelId: event.target.value.trim() } : entry
                          )
                        }))
                      }
                      placeholder="123456789012345678"
                    />
                  </div>
                  <Button
                    type="button"
                    variant="ghost"
                    size="icon"
                    aria-label={t('common.remove')}
                    onClick={() =>
                      setValue((prev) => ({
                        ...prev,
                        logChannels: prev.logChannels.filter((entry) => entry.clientKey !== mapping.clientKey)
                      }))
                    }
                  >
                    <Trash2 className="size-4" />
                  </Button>
                </div>
              ))}
              <Button
                type="button"
                variant="outline"
                onClick={() =>
                  setValue((prev) => ({
                    ...prev,
                    logChannels: [
                      ...prev.logChannels,
                      { clientKey: `new-${Date.now()}`, eventType: 'MOD_ACTION', channelId: '' }
                    ]
                  }))
                }
              >
                <Plus className="size-4" />
                {t('modulePages.logging.addMapping')}
              </Button>
            </CardContent>
          </Card>
          </FieldAnchor>
        </div>
      )}
    </SettingsForm>
  );
}
