import { useEffect, useState } from 'react';
import { api } from '../lib/api.ts';
import { useServerStore } from '../stores/server.ts';

interface ServerSettingsModalProps {
  serverId: string;
  onClose: () => void;
}

interface AuditEntry {
  id: string;
  server_id: string;
  user_id: string | null;
  username: string | null;
  action_type: string;
  target_type: string | null;
  target_id: string | null;
  reason: string | null;
  changes: unknown;
  created_at: string;
}

interface AvailabilitySlot {
  day_of_week: string;
  start_time: string;
  end_time: string;
}

const ACTION_LABELS: Record<string, string> = {
  KICK: 'kicked member',
  BAN: 'banned member',
  UNBAN: 'unbanned member',
  MUTE: 'muted member',
  UNMUTE: 'unmuted member',
  ROLE_CREATE: 'created role',
  ROLE_UPDATE: 'updated role',
  ROLE_DELETE: 'deleted role',
  MEMBER_ROLES_UPDATE: 'updated member roles',
  CHANNEL_CREATE: 'created channel',
  CHANNEL_UPDATE: 'updated channel',
  CHANNEL_DELETE: 'deleted channel',
  SERVER_UPDATE: 'updated server',
  MESSAGE_DELETE: 'deleted message',
  BULK_DELETE: 'bulk deleted messages',
};

const DAYS = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'];

export function ServerSettingsModal({ serverId, onClose }: ServerSettingsModalProps) {
  const [tab, setTab] = useState<'audit' | 'availability'>('audit');
  const [entries, setEntries] = useState<AuditEntry[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const servers = useServerStore((s) => s.servers);
  const server = servers.find((s) => s.id === serverId);

  // Availability state
  const [slots, setSlots] = useState<AvailabilitySlot[]>([]);
  const [availLoading, setAvailLoading] = useState(false);
  const [availMessage, setAvailMessage] = useState<string | null>(null);
  const [editDay, setEditDay] = useState('monday');
  const [editStart, setEditStart] = useState('09:00');
  const [editEnd, setEditEnd] = useState('17:00');

  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === 'Escape') {
        e.preventDefault();
        onClose();
      }
    };
    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [onClose]);

  useEffect(() => {
    if (tab === 'audit') {
      setLoading(true);
      setError(null);
      api.get<AuditEntry[]>(`/servers/${serverId}/audit-log`)
        .then((data) => setEntries(Array.isArray(data) ? data : []))
        .catch((err) => setError(err instanceof Error ? err.message : 'Failed to load audit log'))
        .finally(() => setLoading(false));
    } else if (tab === 'availability') {
      setAvailLoading(true);
      api.get<AvailabilitySlot[]>(`/users/me/availability?server_id=${serverId}`)
        .then((data) => setSlots(Array.isArray(data) ? data : []))
        .catch(() => {})
        .finally(() => setAvailLoading(false));
    }
  }, [tab, serverId]);

  const formatTime = (iso: string) => {
    const d = new Date(iso);
    return d.toLocaleString();
  };

  const addSlot = () => {
    if (slots.some((s) => s.day_of_week === editDay && s.start_time === editStart)) return;
    setSlots([...slots, { day_of_week: editDay, start_time: editStart, end_time: editEnd }]);
  };

  const removeSlot = (idx: number) => {
    setSlots(slots.filter((_, i) => i !== idx));
  };

  const saveSlots = async () => {
    setAvailMessage(null);
    try {
      await api.put(`/users/me/availability?server_id=${serverId}`, slots);
      setAvailMessage('[saved]');
    } catch (err) {
      setAvailMessage(err instanceof Error ? `ERR: ${err.message}` : 'ERR: failed to save');
    }
  };

  const slotsForDay = (day: string) => slots.filter((s) => s.day_of_week === day);

  return (
    <div
      className="fixed inset-0 bg-black/50 flex items-center justify-center z-50"
      onClick={onClose}
    >
      <div
        className="bg-gb-bg border border-gb-bg-t w-[700px] max-h-[80vh] flex flex-col font-mono"
        onClick={(e) => e.stopPropagation()}
      >
        <div className="flex items-center justify-between px-4 py-3 border-b border-gb-bg-t">
          <span className="text-sm text-gb-orange">SERVER SETTINGS: {server?.name ?? serverId}</span>
          <button onClick={onClose} className="text-xs text-gb-red">[x]</button>
        </div>
        <div className="flex border-b border-gb-bg-t">
          <button
            onClick={() => setTab('audit')}
            className={`px-4 py-2 text-xs ${tab === 'audit' ? 'text-gb-orange bg-gb-bg-s' : 'text-gb-fg-f hover:text-gb-orange'}`}
          >
            [AUDIT LOG]
          </button>
          <button
            onClick={() => setTab('availability')}
            className={`px-4 py-2 text-xs ${tab === 'availability' ? 'text-gb-orange bg-gb-bg-s' : 'text-gb-fg-f hover:text-gb-orange'}`}
          >
            [AVAILABILITY]
          </button>
        </div>
        <div className="flex-1 overflow-y-auto p-4">
          {tab === 'audit' && (
            <>
              {loading && <p className="text-gb-fg-f text-xs">[loading...]</p>}
              {error && <p className="text-gb-red text-xs">ERR: {error}</p>}
              {!loading && !error && entries.length === 0 && (
                <p className="text-gb-fg-f text-xs">[no audit log entries]</p>
              )}
              <div className="space-y-2">
                {entries.map((entry) => (
                  <div key={entry.id} className="text-xs border border-gb-bg-t p-2 bg-gb-bg-s">
                    <div className="flex items-center justify-between text-gb-fg-f">
                      <span>{formatTime(entry.created_at)}</span>
                      <span className="text-gb-orange">{entry.action_type}</span>
                    </div>
                    <div className="text-gb-fg mt-1">
                      <span className="text-gb-aqua">{entry.username ?? entry.user_id ?? 'system'}</span>
                      {' '}<span className="text-gb-fg-s">{ACTION_LABELS[entry.action_type] ?? entry.action_type}</span>
                      {entry.target_id && (
                        <span className="text-gb-fg-f"> target:{entry.target_id}</span>
                      )}
                    </div>
                    {entry.reason && (
                      <div className="text-gb-fg-f mt-1">reason: {entry.reason}</div>
                    )}
                  </div>
                ))}
              </div>
            </>
          )}
          {tab === 'availability' && (
            <div className="space-y-4">
              {availLoading && <p className="text-gb-fg-f text-xs">[loading...]</p>}
              <div className="text-xs text-gb-fg-s mb-2">set your weekly availability for this server</div>

              {/* Add slot form */}
              <div className="flex items-center gap-2 flex-wrap">
                <select
                  value={editDay}
                  onChange={(e) => setEditDay(e.target.value)}
                  className="terminal-input text-xs py-1 px-2"
                >
                  {DAYS.map((d) => <option key={d} value={d}>{d.slice(0,3)}</option>)}
                </select>
                <input
                  type="time"
                  value={editStart}
                  onChange={(e) => setEditStart(e.target.value)}
                  className="terminal-input text-xs py-1 px-2 w-20"
                />
                <span className="text-gb-fg-f text-xs">to</span>
                <input
                  type="time"
                  value={editEnd}
                  onChange={(e) => setEditEnd(e.target.value)}
                  className="terminal-input text-xs py-1 px-2 w-20"
                />
                <button onClick={addSlot} className="px-2 py-1 bg-gb-orange text-gb-bg text-xs">[ADD]</button>
              </div>

              {/* Grid by day */}
              <div className="grid grid-cols-7 gap-1">
                {DAYS.map((day) => (
                  <div key={day} className="text-xs">
                    <div className="text-gb-orange font-bold mb-1 text-center">{day.slice(0,3)}</div>
                    <div className="space-y-1">
                      {slotsForDay(day).map((s, i) => {
                        const globalIdx = slots.findIndex((x) => x === slots.filter((sl) => sl.day_of_week === day)[i]);
                        return (
                          <div key={globalIdx} className="bg-gb-bg-t rounded px-1 py-0.5 flex items-center justify-between gap-1 group">
                            <span className="text-gb-fg-s">{s.start_time}-{s.end_time}</span>
                            <button
                              onClick={() => removeSlot(globalIdx)}
                              className="text-gb-fg-f hover:text-gb-red opacity-0 group-hover:opacity-100"
                            >✕</button>
                          </div>
                        );
                      })}
                    </div>
                  </div>
                ))}
              </div>

              <div className="flex items-center gap-2">
                <button onClick={saveSlots} className="px-3 py-1 bg-gb-orange text-gb-bg text-xs">[SAVE]</button>
                {availMessage && <span className="text-xs text-gb-fg-s">{availMessage}</span>}
              </div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}
