import { Component, createSignal, For, Show } from 'solid-js';
import { A, useLocation } from '@solidjs/router';
import { createTRPCClient } from '../../trpc/client';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useAuth } from '../../lib/auth';
import type { Team as DbTeam, TeamMember as DbTeamMember } from '../../db/schema/teams';

const API_URL = (import.meta as any).env?.VITE_API_URL || 'http://localhost:8080';

function formatDateTime(iso: Date | string): string {
  return new Date(iso).toLocaleDateString('en-US', {
    month: 'short',
    day: 'numeric',
    year: 'numeric',
  });
}

function getAuthToken(): string | null {
  const token = localStorage.getItem('clerk_token');
  return token || null;
}

const TeamList: Component = () => {
  const queryClient = useQueryClient();
  const client = createTRPCClient(API_URL);
  const auth = useAuth();
  const [showCreateDialog, setShowCreateDialog] = createSignal(false);
  const [newTeamName, setNewTeamName] = createSignal('');
  const [error, setError] = createSignal('');

  const teamsQuery = useQuery({
    queryKey: ['team', 'listTeams'],
    queryFn: async () => {
      const token = getAuthToken();
      const res = await fetch(`${API_URL}/trpc/team.listTeams`, {
        headers: token ? { Authorization: `Bearer ${token}` } : {},
      });
      if (!res.ok) throw new Error('Failed to fetch teams');
      const data = await res.json();
      return data.data as DbTeam[];
    },
  });

  const createTeamMutation = useMutation({
    mutationFn: async (name: string) => {
      const token = getAuthToken();
      const res = await fetch(`${API_URL}/trpc/team.createTeam`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          ...(token ? { Authorization: `Bearer ${token}` } : {}),
        },
        body: JSON.stringify({ input: { name } }),
      });
      if (!res.ok) {
        const err = await res.json().catch(() => ({}));
        throw new Error(err.message || 'Failed to create team');
      }
      return res.json();
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['team', 'listTeams'] });
      setShowCreateDialog(false);
      setNewTeamName('');
    },
    onError: (err) => setError(err.message),
  });

  const deleteTeamMutation = useMutation({
    mutationFn: async (id: string) => {
      const token = getAuthToken();
      const res = await fetch(`${API_URL}/trpc/team.deleteTeam`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          ...(token ? { Authorization: `Bearer ${token}` } : {}),
        },
        body: JSON.stringify({ input: { id } }),
      });
      if (!res.ok) throw new Error('Failed to delete team');
      return res.json();
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['team', 'listTeams'] });
    },
  });

  return (
    <div class="freno-teams">
      <div class="freno-page-header">
        <h1>Teams</h1>
        <button
          class="freno-btn freno-btn-primary"
          onClick={() => { setShowCreateDialog(true); setError(''); }}
        >
          + New Team
        </button>
      </div>

      {error() && (
        <div class="freno-alert freno-alert-error">
          {error()}
          <button onClick={() => setError('')} class="freno-alert-dismiss">×</button>
        </div>
      )}

      {teamsQuery.isLoading ? (
        <div class="freno-loading">Loading teams...</div>
      ) : teamsQuery.error ? (
        <div class="freno-empty-state">
          <div class="freno-empty-icon">⚠️</div>
          <h3>Failed to load teams</h3>
          <p>{teamsQuery.error.message}</p>
          <button class="freno-btn freno-btn-secondary" onClick={() => teamsQuery.refetch()}>
            Retry
          </button>
        </div>
      ) : (
        <div class="freno-team-grid">
          <For each={teamsQuery.data || []}>
            {(team) => (
              <div class="freno-team-card">
                <A href={`/teams/${team.id}`} class="freno-team-card-link">
                  <div class="freno-team-icon">👥</div>
                  <h3>{team.name}</h3>
                  <span class="freno-date">
                    Created {formatDateTime(team.createdAt)}
                  </span>
                </A>
                <div class="freno-team-card-actions">
                  <button
                    class="freno-btn freno-btn-danger-sm"
                    onClick={(e) => {
                      e.preventDefault();
                      e.stopPropagation();
                      if (confirm(`Delete team "${team.name}"? This cannot be undone.`)) {
                        deleteTeamMutation.mutate(team.id);
                      }
                    }}
                    disabled={deleteTeamMutation.isPending}
                  >
                    Delete
                  </button>
                </div>
              </div>
            )}
          </For>

          <button
            class="freno-team-card freno-team-card-new"
            onClick={() => { setShowCreateDialog(true); setError(''); }}
          >
            <div class="freno-team-icon">+</div>
            <h3>Create Team</h3>
          </button>
        </div>
      )}

      {showCreateDialog() && (
        <div class="freno-modal-overlay" onClick={() => setShowCreateDialog(false)}>
          <div class="freno-modal" onClick={(e) => e.stopPropagation()}>
            <div class="freno-modal-header">
              <h2>Create New Team</h2>
              <button class="freno-btn-icon" onClick={() => setShowCreateDialog(false)}>✕</button>
            </div>
            <form class="freno-form" onSubmit={(e) => {
              e.preventDefault();
              const name = newTeamName().trim();
              if (name) {
                setError('');
                createTeamMutation.mutate(name);
              }
            }}>
              <div class="freno-form-group">
                <label class="freno-label" for="team-name">Team Name</label>
                <input
                  class="freno-input"
                  id="team-name"
                  type="text"
                  placeholder="My Writing Team"
                  value={newTeamName()}
                  onInput={(e) => setNewTeamName(e.target.value)}
                  autofocus
                  required
                />
              </div>
              <div class="freno-form-actions">
                <button
                  type="submit"
                  class="freno-btn freno-btn-primary"
                  disabled={createTeamMutation.isPending || !newTeamName().trim()}
                >
                  {createTeamMutation.isPending ? 'Creating...' : 'Create Team'}
                </button>
                <button
                  type="button"
                  class="freno-btn freno-btn-secondary"
                  onClick={() => setShowCreateDialog(false)}
                >
                  Cancel
                </button>
              </div>
            </form>
          </div>
        </div>
      )}
    </div>
  );
};

const TeamDetail: Component<{ teamId: string }> = ({ teamId }) => {
  const queryClient = useQueryClient();
  const auth = useAuth();
  const [error, setError] = createSignal('');
  const [showInviteDialog, setShowInviteDialog] = createSignal(false);
  const [inviteUserId, setInviteUserId] = createSignal('');
  const [inviteRole, setInviteRole] = createSignal<'editor' | 'viewer' | 'admin'>('editor');

  const teamQuery = useQuery({
    queryKey: ['team', 'getTeam', teamId],
    queryFn: async () => {
      const token = getAuthToken();
      const res = await fetch(`${API_URL}/trpc/team.getTeam?input=${encodeURIComponent(JSON.stringify({ id: teamId }))}`, {
        headers: token ? { Authorization: `Bearer ${token}` } : {},
      });
      if (!res.ok) throw new Error('Failed to fetch team');
      const data = await res.json();
      return data.data as DbTeam;
    },
  });

  const membersQuery = useQuery({
    queryKey: ['team', 'listMembers', teamId],
    queryFn: async () => {
      const token = getAuthToken();
      const res = await fetch(`${API_URL}/trpc/team.listMembers?input=${encodeURIComponent(JSON.stringify({ teamId }))}`, {
        headers: token ? { Authorization: `Bearer ${token}` } : {},
      });
      if (!res.ok) throw new Error('Failed to fetch members');
      const data = await res.json();
      return data.data as DbTeamMember[];
    },
  });

  const updateRoleMutation = useMutation({
    mutationFn: async ({ userId, role }: { userId: number; role: string }) => {
      const token = getAuthToken();
      const res = await fetch(`${API_URL}/trpc/team.updateMemberRole`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          ...(token ? { Authorization: `Bearer ${token}` } : {}),
        },
        body: JSON.stringify({ input: { teamId, userId, role } }),
      });
      if (!res.ok) throw new Error('Failed to update role');
      return res.json();
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['team', 'listMembers', teamId] });
    },
    onError: (err) => setError(err.message),
  });

  const removeMemberMutation = useMutation({
    mutationFn: async (userId: number) => {
      const token = getAuthToken();
      const res = await fetch(`${API_URL}/trpc/team.removeMember`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          ...(token ? { Authorization: `Bearer ${token}` } : {}),
        },
        body: JSON.stringify({ input: { teamId, userId } }),
      });
      if (!res.ok) throw new Error('Failed to remove member');
      return res.json();
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['team', 'listMembers', teamId] });
    },
    onError: (err) => setError(err.message),
  });

  const leaveTeamMutation = useMutation({
    mutationFn: async () => {
      const token = getAuthToken();
      const res = await fetch(`${API_URL}/trpc/team.leaveTeam`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          ...(token ? { Authorization: `Bearer ${token}` } : {}),
        },
        body: JSON.stringify({ input: { teamId } }),
      });
      if (!res.ok) throw new Error('Failed to leave team');
      return res.json();
    },
    onSuccess: () => {
      window.location.href = '/teams';
    },
    onError: (err) => setError(err.message),
  });

  const addMemberMutation = useMutation({
    mutationFn: async ({ userId, role }: { userId: number; role: string }) => {
      const token = getAuthToken();
      const res = await fetch(`${API_URL}/trpc/team.addMember`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          ...(token ? { Authorization: `Bearer ${token}` } : {}),
        },
        body: JSON.stringify({ input: { teamId, userId, role } }),
      });
      if (!res.ok) {
        const err = await res.json().catch(() => ({}));
        throw new Error(err.message || 'Failed to add member');
      }
      return res.json();
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['team', 'listMembers', teamId] });
      setShowInviteDialog(false);
      setInviteUserId('');
    },
    onError: (err) => setError(err.message),
  });

  return (
    <div class="freno-team-detail">
      <div class="freno-page-header">
        <div>
          <A href="/teams" class="freno-back-link">← Back to Teams</A>
          <h1>
            {teamQuery.isLoading ? 'Loading...' : teamQuery.data?.name || 'Team'}
          </h1>
          <p class="freno-team-meta">
            Created {teamQuery.data ? formatDateTime(teamQuery.data.createdAt) : ''}
          </p>
        </div>
        <div class="freno-header-actions">
          <button
            class="freno-btn freno-btn-primary"
            onClick={() => setShowInviteDialog(true)}
          >
            + Invite Member
          </button>
          <button
            class="freno-btn freno-btn-danger"
            onClick={() => {
              if (confirm('Leave this team? You will lose access to shared projects.')) {
                leaveTeamMutation.mutate();
              }
            }}
            disabled={leaveTeamMutation.isPending}
          >
            Leave Team
          </button>
        </div>
      </div>

      {error() && (
        <div class="freno-alert freno-alert-error">
          {error()}
          <button onClick={() => setError('')} class="freno-alert-dismiss">×</button>
        </div>
      )}

      <div class="freno-team-members-section">
        <h2>Members ({membersQuery.data?.length || 0})</h2>

        {membersQuery.isLoading ? (
          <div class="freno-loading">Loading members...</div>
        ) : membersQuery.error ? (
          <div class="freno-empty-state">
            <p>Failed to load members: {membersQuery.error.message}</p>
            <button class="freno-btn freno-btn-secondary" onClick={() => membersQuery.refetch()}>
              Retry
            </button>
          </div>
        ) : (membersQuery.data || []).length === 0 ? (
          <div class="freno-empty-state">
            <div class="freno-empty-icon">👤</div>
            <h3>No members yet</h3>
            <p>Invite people to collaborate with your team.</p>
          </div>
        ) : (
          <div class="freno-members-list">
            <For each={membersQuery.data || []}>
              {(member) => (
                <div class="freno-member-row">
                  <div class="freno-member-info">
                    <span class="freno-member-id">User #{member.userId}</span>
                    <span class="freno-member-joined">Joined {formatDateTime(member.joinedAt)}</span>
                  </div>
                  <div class="freno-member-actions">
                    <select
                      class="freno-select"
                      value={member.role}
                      onChange={(e) => {
                        setError('');
                        updateRoleMutation.mutate({ userId: member.userId, role: e.target.value });
                      }}
                    >
                      <option value="owner">Owner</option>
                      <option value="admin">Admin</option>
                      <option value="editor">Editor</option>
                      <option value="viewer">Viewer</option>
                    </select>
                    <button
                      class="freno-btn freno-btn-danger-sm"
                      onClick={() => {
                        if (confirm(`Remove this member from the team?`)) {
                          removeMemberMutation.mutate(member.userId);
                        }
                      }}
                      disabled={member.role === 'owner'}
                    >
                      Remove
                    </button>
                  </div>
                </div>
              )}
            </For>
          </div>
        )}
      </div>

      {showInviteDialog() && (
        <div class="freno-modal-overlay" onClick={() => setShowInviteDialog(false)}>
          <div class="freno-modal" onClick={(e) => e.stopPropagation()}>
            <div class="freno-modal-header">
              <h2>Invite Member</h2>
              <button class="freno-btn-icon" onClick={() => setShowInviteDialog(false)}>✕</button>
            </div>
            <form class="freno-form" onSubmit={(e) => {
              e.preventDefault();
              setError('');
              const userId = parseInt(inviteUserId(), 10);
              if (isNaN(userId) || userId <= 0) {
                setError('Please enter a valid user ID.');
                return;
              }
              addMemberMutation.mutate({ userId, role: inviteRole() });
            }}>
              <div class="freno-form-group">
                <label class="freno-label" for="invite-user-id">User ID</label>
                <input
                  class="freno-input"
                  id="invite-user-id"
                  type="number"
                  placeholder="Enter user ID"
                  value={inviteUserId()}
                  onInput={(e) => setInviteUserId(e.target.value)}
                  required
                />
              </div>
              <div class="freno-form-group">
                <label class="freno-label" for="invite-role">Role</label>
                <select
                  class="freno-select"
                  id="invite-role"
                  value={inviteRole()}
                  onChange={(e) => setInviteRole(e.target.value as 'editor' | 'viewer' | 'admin')}
                >
                  <option value="editor">Editor</option>
                  <option value="viewer">Viewer</option>
                  <option value="admin">Admin</option>
                </select>
              </div>
              <div class="freno-form-actions">
                <button
                  type="submit"
                  class="freno-btn freno-btn-primary"
                  disabled={addMemberMutation.isPending || !inviteUserId()}
                >
                  {addMemberMutation.isPending ? 'Inviting...' : 'Invite'}
                </button>
                <button
                  type="button"
                  class="freno-btn freno-btn-secondary"
                  onClick={() => setShowInviteDialog(false)}
                >
                  Cancel
                </button>
              </div>
            </form>
          </div>
        </div>
      )}
    </div>
  );
};

export const TeamManagement: Component<any> = (props) => {
  const location = useLocation();
  const teamId = () => {
    const match = location.pathname.match(/^\/teams\/([^/]+)$/);
    return match ? match[1] : null;
  };

  return (
    <>
      <Show when={!teamId()} fallback={<TeamDetail teamId={teamId()!} />}>
        <TeamList />
      </Show>
    </>
  );
};


