import {
  DeesElement,
  html,
  customElement,
  type TemplateResult,
  css,
  state,
  cssManager,
} from '@design.estate/dees-element';
import * as appstate from '../../appstate.js';
import * as interfaces from '../../../dist_ts_interfaces/index.js';
import { viewHostCss } from '../shared/css.js';
import { type IStatsTile } from '@design.estate/dees-catalog';

declare global {
  interface HTMLElementTagNameMap {
    'ops-view-sourceprofiles': OpsViewSourceProfiles;
  }
}

@customElement('ops-view-sourceprofiles')
export class OpsViewSourceProfiles extends DeesElement {
  @state()
  accessor profilesState: appstate.IProfilesTargetsState = appstate.profilesTargetsStatePart.getState()!;

  constructor() {
    super();
    const sub = appstate.profilesTargetsStatePart.select().subscribe((newState) => {
      this.profilesState = newState;
    });
    this.rxSubscriptions.push(sub);
  }

  async connectedCallback() {
    await super.connectedCallback();
    await appstate.profilesTargetsStatePart.dispatchAction(appstate.fetchProfilesAndTargetsAction, null);
  }

  public static styles = [
    cssManager.defaultStyles,
    viewHostCss,
    css`
      .profilesContainer {
        display: flex;
        flex-direction: column;
        gap: 24px;
      }
    `,
  ];

  public render(): TemplateResult {
    const profiles = this.profilesState.profiles;

    const statsTiles: IStatsTile[] = [
      {
        id: 'totalProfiles',
        title: 'Total Profiles',
        type: 'number',
        value: profiles.length,
        icon: 'lucide:shieldCheck',
        description: 'Reusable source profiles',
        color: '#3b82f6',
      },
    ];

    return html`
      <dees-heading level="3">Source Profiles</dees-heading>
      <div class="profilesContainer">
        <dees-statsgrid .tiles=${statsTiles}></dees-statsgrid>
        <dees-table
          .heading1=${'Source Profiles'}
          .heading2=${'Reusable source configurations for routes'}
          .data=${profiles}
          .showColumnFilters=${true}
          .displayFunction=${(profile: interfaces.data.ISourceProfile) => ({
            Name: profile.name,
            Description: profile.description || '-',
            'IP Allow List': (profile.security?.ipAllowList || []).join(', ') || '-',
            'IP Block List': (profile.security?.ipBlockList || []).join(', ') || '-',
            'Max Connections': profile.security?.maxConnections ?? '-',
            'Rate Limit': profile.security?.rateLimit?.enabled ? `${profile.security.rateLimit.maxRequests}/${profile.security.rateLimit.window}s` : '-',
            Extends: (profile.extendsProfiles || []).length > 0
              ? profile.extendsProfiles!.map(id => {
                  const p = profiles.find(pp => pp.id === id);
                  return p ? p.name : id.slice(0, 8);
                }).join(', ')
              : '-',
          })}
          .dataActions=${[
            {
              name: 'Create Profile',
              iconName: 'lucide:plus',
              type: ['header' as const],
              actionFunc: async () => {
                await this.showCreateProfileDialog();
              },
            },
            {
              name: 'Refresh',
              iconName: 'lucide:rotateCw',
              type: ['header' as const],
              actionFunc: async () => {
                await appstate.profilesTargetsStatePart.dispatchAction(appstate.fetchProfilesAndTargetsAction, null);
              },
            },
            {
              name: 'Edit',
              iconName: 'lucide:pencil',
              type: ['inRow', 'contextmenu'] as any,
              actionFunc: async (actionData: any) => {
                const profile = actionData.item as interfaces.data.ISourceProfile;
                await this.showEditProfileDialog(profile);
              },
            },
            {
              name: 'Delete',
              iconName: 'lucide:trash2',
              type: ['inRow', 'contextmenu'] as any,
              actionFunc: async (actionData: any) => {
                const profile = actionData.item as interfaces.data.ISourceProfile;
                await this.deleteProfile(profile);
              },
            },
          ]}
        ></dees-table>
      </div>
    `;
  }

  private async showCreateProfileDialog() {
    const { DeesModal } = await import('@design.estate/dees-catalog');
    DeesModal.createAndShow({
      heading: 'Create Source Profile',
      content: html`
        <dees-form>
          <dees-input-text .key=${'name'} .label=${'Name'} .required=${true}></dees-input-text>
          <dees-input-text .key=${'description'} .label=${'Description'}></dees-input-text>
          <dees-input-list .key=${'ipAllowList'} .label=${'IP Allow List'} .placeholder=${'Add IP or CIDR...'}></dees-input-list>
          <dees-input-list .key=${'ipBlockList'} .label=${'IP Block List'} .placeholder=${'Add IP or CIDR...'}></dees-input-list>
          <dees-input-text .key=${'maxConnections'} .label=${'Max Connections'}></dees-input-text>
        </dees-form>
      `,
      menuOptions: [
        { name: 'Cancel', action: async (modalArg: any) => modalArg.destroy() },
        {
          name: 'Create',
          action: async (modalArg: any) => {
            const form = modalArg.shadowRoot?.querySelector('.content')?.querySelector('dees-form');
            if (!form) return;
            const data = await form.collectFormData();
            const ipAllowList: string[] = Array.isArray(data.ipAllowList) ? data.ipAllowList : [];
            const ipBlockList: string[] = Array.isArray(data.ipBlockList) ? data.ipBlockList : [];
            const parsed = data.maxConnections ? parseInt(String(data.maxConnections), 10) : NaN;
            const maxConnections = Number.isNaN(parsed) ? undefined : parsed;

            await appstate.profilesTargetsStatePart.dispatchAction(appstate.createProfileAction, {
              name: String(data.name),
              description: data.description ? String(data.description) : undefined,
              security: {
                ...(ipAllowList.length > 0 ? { ipAllowList } : {}),
                ...(ipBlockList.length > 0 ? { ipBlockList } : {}),
                ...(maxConnections ? { maxConnections } : {}),
              },
            });
            modalArg.destroy();
          },
        },
      ],
    });
  }

  private async showEditProfileDialog(profile: interfaces.data.ISourceProfile) {
    const { DeesModal } = await import('@design.estate/dees-catalog');
    DeesModal.createAndShow({
      heading: `Edit Profile: ${profile.name}`,
      content: html`
        <dees-form>
          <dees-input-text .key=${'name'} .label=${'Name'} .value=${profile.name}></dees-input-text>
          <dees-input-text .key=${'description'} .label=${'Description'} .value=${profile.description || ''}></dees-input-text>
          <dees-input-list .key=${'ipAllowList'} .label=${'IP Allow List'} .placeholder=${'Add IP or CIDR...'} .value=${profile.security?.ipAllowList || []}></dees-input-list>
          <dees-input-list .key=${'ipBlockList'} .label=${'IP Block List'} .placeholder=${'Add IP or CIDR...'} .value=${profile.security?.ipBlockList || []}></dees-input-list>
          <dees-input-text .key=${'maxConnections'} .label=${'Max Connections'} .value=${String(profile.security?.maxConnections || '')}></dees-input-text>
        </dees-form>
      `,
      menuOptions: [
        { name: 'Cancel', action: async (modalArg: any) => modalArg.destroy() },
        {
          name: 'Save',
          action: async (modalArg: any) => {
            const form = modalArg.shadowRoot?.querySelector('.content')?.querySelector('dees-form');
            if (!form) return;
            const data = await form.collectFormData();
            const ipAllowList: string[] = Array.isArray(data.ipAllowList) ? data.ipAllowList : [];
            const ipBlockList: string[] = Array.isArray(data.ipBlockList) ? data.ipBlockList : [];
            const parsed = data.maxConnections ? parseInt(String(data.maxConnections), 10) : NaN;
            const maxConnections = Number.isNaN(parsed) ? undefined : parsed;

            await appstate.profilesTargetsStatePart.dispatchAction(appstate.updateProfileAction, {
              id: profile.id,
              name: String(data.name),
              description: data.description ? String(data.description) : undefined,
              security: {
                ipAllowList,
                ipBlockList,
                ...(maxConnections ? { maxConnections } : {}),
              },
            });
            modalArg.destroy();
          },
        },
      ],
    });
  }

  private async deleteProfile(profile: interfaces.data.ISourceProfile) {
    await appstate.profilesTargetsStatePart.dispatchAction(appstate.deleteProfileAction, {
      id: profile.id,
      force: false,
    });

    const currentState = appstate.profilesTargetsStatePart.getState()!;
    if (currentState.error?.includes('in use')) {
      const { DeesModal } = await import('@design.estate/dees-catalog');
      DeesModal.createAndShow({
        heading: 'Profile In Use',
        content: html`<p>${currentState.error} Force delete?</p>`,
        menuOptions: [
          {
            name: 'Force Delete',
            action: async (modalArg: any) => {
              await appstate.profilesTargetsStatePart.dispatchAction(appstate.deleteProfileAction, {
                id: profile.id,
                force: true,
              });
              modalArg.destroy();
            },
          },
          { name: 'Cancel', action: async (modalArg: any) => modalArg.destroy() },
        ],
      });
    }
  }
}
